Альтернатива использованию локальных переменных в предложении where - PullRequest
1 голос
/ 08 марта 2011

У меня есть запрос, в котором есть предложение where, построенное с использованием ряда локальных переменных. Однако это очень медленно.Ниже приведен грубый пример, поскольку у меня нет доступа к запросу в настоящее время:

declare @a varchar(50), @b varchar(50), @c varchar(50)
set @a = '%'
set @b = 'foo'
set @c = '%bar'

Мое условие where содержит что-то вроде

where a = @a and b = @b and c =@c

Это займет около 1 минуты.Тем не менее, если я непосредственно ссылаюсь на значения в предложении where, такие как:

where a = '%' and b = 'foo' and '%bar'

Это займет около 5 секунд.

Поэтому мой вопрос заключается в том, есть ли лучший способ для создания моего гдестатья?Одна важная вещь, чтобы отметить.В предложении where используется около 10 локальных переменных, но для большинства из них установлено значение по умолчанию%

Заранее спасибо

Ответы [ 4 ]

6 голосов
/ 22 июня 2011

Использование локальных переменных в фильтре WHERE приводит к полному просмотру таблицы.Потому что SS не знает значений локальных переменных во время компиляции.Таким образом, он создает план выполнения для наибольшего масштаба, который может быть доступен для столбца.

Чтобы предотвратить проблему с производительностью, SS должен знать значения переменных во время компиляции.Определение SP и передача этих локальных переменных в качестве параметра является одним из решений проблемы.Другое решение заключается в использовании sp_executesql и повторной передаче этих локальных переменных в качестве параметра ...

Или вы можете добавить OPTION (RECOMPILE) в конце вашего sqlзаявление, чтобы ваши локальные переменные были скомпилированы.Это решит проблему исполнителей.

4 голосов
/ 08 марта 2011

номер

Для констант оптимизатор может разработать лучший план на основе статистики для заданных значений.

Когда вы используете переменную, вы форсируете параметризацию, и план будет разработан для повторного использования для широкого диапазона значений.

В этом случае вы можете попробовать ОПТИМИЗИРОВАТЬ ДЛЯ НЕИЗВЕСТНЫХ , что может дать лучшие результаты. Или не фильтруйте так: используйте разные запросы для разных перестановок. Вам тоже нравятся лидирующие символы?

0 голосов
/ 08 марта 2011

Optimise for unknown, данное gbn, может работать в некоторых случаях, но в других случаях OPTION RECOMPILE может быть лучшим выбором.

Для простых запросов к набору данных, который варьируется между крайними значениями, OPTION RECOMPILE дает вам лучший план для каждого случая, потому что он фактически планирует каждый запрос, используя статические значения (стоимость плана для каждого выполнения), но OPTIMISE FOR UNKNOWN вызывает общий план, который может быть не лучшим в любом случае, и является средним для всех случаев (кэшированный план).

Пример использования

select top 10 * from master..spt_values
OPTION (RECOMPILE)

В SQL Server 2005 были некоторые ошибки в крайнем случае с OPTION RECOMPILE, но он отлично работает в 2008 году.

0 голосов
/ 08 марта 2011

Это становится грязным и может привести к новому набору проблем, но вы можете оценить преобразование этого в динамический SQL. По сути, вы конструируете предложение where во время выполнения, основываясь на том, какие параметры содержат значения (не подстановочные).

Это одна из лучших динамических записей SQL, которые я нашел: http://www.sommarskog.se/dynamic_sql.html

А вот другой, где он специально обращается к динамическим операторам where: http://www.sommarskog.se/dyn-search-2005.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...