Падение производительности ХП в 6 раз на FB 2.1.3
Добавлено: 18 фев 2015, 06:24
Добрый день. Перевожу проект с FB 1.5 на FB 2.1 (Перевод осуществляется путем бэкапа на 1.5 и рестора на 2.1, ошибок не возникает). Появились жалобы на замедление работы приложения. Выяснил конкретное место падения производительности, это хранимая процедура. Поставил на одном компьютере два сервера FB 1.5 и 2.1 на разных портах, оба в режиме SuperServer. Подключаюсь к ним через IBExpert. Запускаю на обоих серверах эту процедуру с одинаковыми параметрами и получаю следующие результаты в Perfomance Analysis:
2.1.7
Plan
------------------------------------------------
PLAN SORT ((GET_PAY_NACH_ON_FS NATURAL))
Query Time
------------------------------------------------
Prepare : 0,00 ms
Execute : 136 141,00 ms
Avg fetch time: 3 889,74 ms
Memory
------------------------------------------------
Current: 10 056 984
Max : 12 458 136
Buffers: 2 048
Operations
------------------------------------------------
Read : 2 138 073
Writes : 0
Fetches: 87 952 817
Marks : 0
Enchanced Info:
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| Table Name | Records Total | Indexed reads | Non-Indexed reads | Updates | Deletes | Inserts | Backouts | Purges | Expunges |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| PR_12 | 415351 | 43850908 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
1.5.6
Plan
------------------------------------------------
PLAN SORT ((GET_PAY_NACH_ON_FS NATURAL))
Query Time
------------------------------------------------
Prepare : 16,00 ms
Execute : 21 171,00 ms
Avg fetch time: 604,89 ms
Memory
------------------------------------------------
Current: 1 090 576
Max : 3 804 348
Buffers: 2 048
Operations
------------------------------------------------
Read : 641 526
Writes : 0
Fetches: 1 713 026
Marks : 0
Enchanced Info:
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| Table Name | Records Total | Indexed reads | Non-Indexed reads | Updates | Deletes | Inserts | Backouts | Purges | Expunges |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| PR_12 | 415351 | 425293 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
Из чего видно, что идет увеличение операций чтения таблицы приблизительно в 100 раз при идентичных результатах самого выполнения...
В хранимой процедуре используется execute statement for и в его цикле еще штук 10 execute statement, возвращающих одно значение. Как я понимаю, оба сервера должны исходить из того, что execute statement по сути не детерминирован и оба сервера должны постоянно перечитывать данные. Но 1.5.6 этого не делает (предполагаю наличие или использование какого-то кэша запросов), в то время как 2.1 - делает.
Возможно я не правильно предполагаю. Так как я проделал опыт с возвращением одной записи в execute statement for и тут количество чтений у 1.5.6 осталось неизменным (т.е. цикл по одной записи с вложенным в него десятком execute statement и цикл по 100 равны между собой по количеству операций чтений), в то время как у 2.1.7 количество чтений стало меньше чем у 1.5.6.
Собственно вопрос, есть ли возможность установкой каких-либо опций сервера 2.1.7 вернуть поведение сервера 1.5.6 в плане работы с execute statement или можно сразу начинать переделывать проект без использования этой процедуры с ее execute statement-ми (этот вариант хотелось бы использовать в последнюю очередь, хотя он, наверное, самый правильный)?
2.1.7
Plan
------------------------------------------------
PLAN SORT ((GET_PAY_NACH_ON_FS NATURAL))
Query Time
------------------------------------------------
Prepare : 0,00 ms
Execute : 136 141,00 ms
Avg fetch time: 3 889,74 ms
Memory
------------------------------------------------
Current: 10 056 984
Max : 12 458 136
Buffers: 2 048
Operations
------------------------------------------------
Read : 2 138 073
Writes : 0
Fetches: 87 952 817
Marks : 0
Enchanced Info:
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| Table Name | Records Total | Indexed reads | Non-Indexed reads | Updates | Deletes | Inserts | Backouts | Purges | Expunges |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| PR_12 | 415351 | 43850908 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
1.5.6
Plan
------------------------------------------------
PLAN SORT ((GET_PAY_NACH_ON_FS NATURAL))
Query Time
------------------------------------------------
Prepare : 16,00 ms
Execute : 21 171,00 ms
Avg fetch time: 604,89 ms
Memory
------------------------------------------------
Current: 1 090 576
Max : 3 804 348
Buffers: 2 048
Operations
------------------------------------------------
Read : 641 526
Writes : 0
Fetches: 1 713 026
Marks : 0
Enchanced Info:
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| Table Name | Records Total | Indexed reads | Non-Indexed reads | Updates | Deletes | Inserts | Backouts | Purges | Expunges |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
| PR_12 | 415351 | 425293 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+--------------------------+-----------+-----------+-------------+---------+---------+---------+----------+----------+----------+
Из чего видно, что идет увеличение операций чтения таблицы приблизительно в 100 раз при идентичных результатах самого выполнения...
В хранимой процедуре используется execute statement for и в его цикле еще штук 10 execute statement, возвращающих одно значение. Как я понимаю, оба сервера должны исходить из того, что execute statement по сути не детерминирован и оба сервера должны постоянно перечитывать данные. Но 1.5.6 этого не делает (предполагаю наличие или использование какого-то кэша запросов), в то время как 2.1 - делает.
Возможно я не правильно предполагаю. Так как я проделал опыт с возвращением одной записи в execute statement for и тут количество чтений у 1.5.6 осталось неизменным (т.е. цикл по одной записи с вложенным в него десятком execute statement и цикл по 100 равны между собой по количеству операций чтений), в то время как у 2.1.7 количество чтений стало меньше чем у 1.5.6.
Собственно вопрос, есть ли возможность установкой каких-либо опций сервера 2.1.7 вернуть поведение сервера 1.5.6 в плане работы с execute statement или можно сразу начинать переделывать проект без использования этой процедуры с ее execute statement-ми (этот вариант хотелось бы использовать в последнюю очередь, хотя он, наверное, самый правильный)?