Время ожидания CFQUERY истекает при использовании cfqueryparams и сервера MSSQL?

Я выполняю запрос, который возвращает около 16000 строк. Выполнение прямого SQL в MS SQL Server Manager возвращает записи за несколько секунд. Выполнение того же SQL в cfquery возвращает его примерно за то же время. Запрос состоит из нескольких переменных, поступающих из аргументов функции. Если дать возможность cfquery оценить переменные, запрос также быстро вернется.

Почему, когда я добавляю cfqueryparam для переменных, а их всего 6, запрос выполняется более часа, а затем истекает время ожидания. Типы cfsql: * cf_sql_integer * и * cf_sql_timestamp *. Как только я их удалю, все готово и работает.


person Danomite    schedule 10.07.2012    source источник
comment
SQL Server иногда делает некоторые странные вещи, если используются параметры (я забываю термин, используемый для этой ситуации, но я думаю, что это связано с неправильными оценками, которые, по крайней мере, в моем случае, использовали LOOP JOINS вместо HASH / MERGE объединений) . Исправление, которое я использовал локально - хотя и для типизированных наборов данных на C # - заключалось в использовании OPTION (RECOMPILE) в запросе, чего было достаточно, чтобы планировщик запросов создал хороший план.   -  person    schedule 11.07.2012
comment
Не знаю, что вызывает это, но вы можете захватить некоторые трассировки стека или что-то еще, чтобы увидеть, не происходит ли что-нибудь очевидное. Также запустите трассировку на сервере БД, чтобы увидеть, общается ли CF с БД, и, возможно, определите, где в цепочке CF- ›JDBC-› DB- ›JDBC-› CF происходит задержка. Какая версия CF, кстати?   -  person Adam Cameron    schedule 11.07.2012
comment
См. stackoverflow.com/questions/8415999/ (иногда создается плохой план?) и stackoverflow.com/questions/2905440/ (плохие типы могут снизить производительность). Кроме того, если используются sprocs, это может быть еще одной проблемой с кешированием.   -  person    schedule 11.07.2012
comment
Лицензия разработчика CF9. К сожалению, у меня нет большого доступа к серверу БД, чтобы действительно взглянуть на журналы и происходящее там. Делает вещи немного сложнее. Что касается перекомпиляции, я предполагаю, что это конкретный вопрос CF, но у меня сложилось впечатление, что CF оценит переменные, а затем передаст полный запрос с оцененными параметрами. EX WHERE name = '# myArgument #' будет просто отправлено на SQL Server как WHERE name = 'dano'. Я попробую OPTION (RECOMPILE) утром и посмотрю, как это работает.   -  person Danomite    schedule 11.07.2012


Ответы (2)


Как правило, cfqueryparam должен работать лучше - не хуже - с cfqueryparam, потому что это должно приводить к лучшим попаданиям в кеш. Однако, если бы он не попал в кеш, он бы создал новый план - результатом был бы немного более медленный запрос, а не тайм-аут. Итак, я предполагаю, что вы на самом деле получаете план выполнения из кеша, и он просто не работает так, как рекламируется.

В качестве теста попробуйте изменить "TYPE" cf_sql_timestamp на cf_sql_char - это вызовет неявное преобразование и другой план, но оставьте cfqueryparam в смеси. Если это сработает и вы получите приемлемый результат, вам нужно очистить кеш запросов (я имею в виду на сервере db) или перекомпилировать план (с перекомпиляцией) и т. Д.

person Mark A Kruger    schedule 10.07.2012

Я думаю, что Марк на правильном пути.

Я предполагаю, что вы работаете с преобразованием типов на SQL Server. Это может привести к действительно плохой производительности, потому что SQL не сможет использовать индекс, И преобразование выполняется для каждой отдельной строки.

Лучший способ подтвердить это - запустить трассировку на SQL Server, чтобы точно увидеть, какой запрос выполняется. Вы также можете проверить типы столбцов и убедиться, что они выровнены по правильным типам данных: http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=Tags_p-q_18.html

person emeier    schedule 11.07.2012