Prepare для запросов execute procedure

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
VerLeon
Сообщения: 44
Зарегистрирован: 24 ноя 2007, 08:43

Prepare для запросов execute procedure

Сообщение VerLeon » 24 ноя 2007, 09:38

Скорее как дополнение к статье "Этот загадочный TIBStoredProc ...",
которую заметил к сожалению слишком поздно
Заметил странную вещь, объяснения которой найти не смог.

Через IBX (хотя пробовал и старый FIB+, дело не в компонентах доступа, имхо) по циклу выполняю запрос типа
execute procedure proc_name ( _params_)

Т.е. заполняется текст запроса, делается prepare, затем по циклу проставляются параметры и запрос выполняется много раз.
Но выполняется это все подозрительно долго.
Больше всего поразило, что поставив exit в начало вызываемой ХП скорость практически не возросла.
Не буду перечислять всех плясок с бубном (если надо могу и перечислить) но вывод был сделан следующий - prepare для запросов вида execute procedure не компилирует запрос и при каждом выполнении такого запрос он заново компилируется, хотя изменились только значения параметров.

В итоге решение нашлось - в ХП был добавлен ненужный выходной параметр, а запрос переформулирован в
select параметр from proc_name ( _params_)

и все стало летать. Но почему?

Скорее всего тут сказывается засада, описанная на сем ресурсе с компонентом TIBStroredProc, а точнее со всеми компонентами IBX и по крайней мере ранних FIB при использовании запросов execute procedure - именно поэтому я и не обратил на эту статью внимания, потому что использовал и TIBQuery и TIBSQL - результат одинаков (на самом деле дело не в конкретном компоненте, описанная в статье "странность" есть во всех компонентах IBX, по-моему статью стоит переименовать).
Но в ту ветку, где вызывается повторный prepare и exec2 я ни разу не попал. Мне кажется, что проблема именно в том, что если при prepare тип запроса был определен как SQLExecProcedure (в терминологии IBX), то реального prepare (а точнее компиляции запроса) ВООБЩЕ не происходит, а происходит он при каждом вызове isc_dsql_exec2, т.е. проблема лежит дальше - в gds32 или вообще в сервере

IB 7.5.1 SP1, IBX 7.09, версию FIB+ не помню, какая-то очень старая

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Re: Prepare для запросов execute procedure

Сообщение dimitr » 25 ноя 2007, 13:26

VerLeon писал(а):кажется, что проблема именно в том, что если при prepare тип запроса был определен как SQLExecProcedure (в терминологии IBX), то реального prepare (а точнее компиляции запроса) ВООБЩЕ не происходит, а происходит он при каждом вызове isc_dsql_exec2, т.е. проблема лежит дальше - в gds32 или вообще в сервере
так оно и есть

VerLeon
Сообщения: 44
Зарегистрирован: 24 ноя 2007, 08:43

Re: Prepare для запросов execute procedure

Сообщение VerLeon » 26 ноя 2007, 08:14

dimitr писал(а): так оно и есть
А можно узнать по какой причине? И как с этим дела обстоят в FB / FB 2?

Вопрос не праздный, раз так сделано, то причина на это видимо есть, а раз так, то вполне вероятно, что переделывая запрос на "select from" я рискую наступить на какие-то еще более серьезные грабли - ведь запрос по сути тот же - а этого очень не хотелось бы. Ну или хотелось бы по крайней мере знать, откуда ждать засады.

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Re: Prepare для запросов execute procedure

Сообщение Dimitry Sibiryakov » 26 ноя 2007, 08:14

dimitr писал(а):так оно и есть
Опаньки... А тому есть внятная причина или это такой способ пофиксить баг с exec2?

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Re: Prepare для запросов execute procedure

Сообщение dimitr » 26 ноя 2007, 08:52

VerLeon писал(а):А можно узнать по какой причине? И как с этим дела обстоят в FB / FB 2?
причина не известна, логика унаследована от IB6. В FB2 и выше все препарится как положено.

Ответить