2015-05-05 2 views
3

Предположим, что у нас есть плохо выполняемая хранимая процедура с 6 параметрами. Если один из шести параметров переносится на локальную переменную в хранимой процедуре, достаточно ли отключить параметр sniffing или необходимо передать все 6 параметров, которые переданы хранимой процедуре в локальные переменные в хранимой процедуре?параметр sniffing

+0

Что такое СУБД? –

+3

Читайте на [SQL Parameter Sniffing] (http://www.brentozar.com/archive/2013/06/the-elephant-and-the-mouse-or-parameter-sniffing-in-sql-server/). Это даст вам четкое представление о том, какой параметр нюхает. –

+1

SQL Server. Версии 8, если быть точным. – knot22

ответ

5

Комментарий Пер Поля Уайта, присваивание переменной локальной переменной является обходным путем из более старых версий SQL Server. Это не поможет с sp_executesql, и Microsoft могла бы написать более разумный синтаксический анализатор, который сделал бы недействительным этот обходной путь. Обходной путь работает, запутывая парсер о значении параметра, поэтому для того, чтобы он работал для каждого параметра, вам нужно было бы сохранить каждый параметр в локальной переменной.

Более свежие версии SQL Server имеют лучшие решения. Для дорогого запроса, который не выполняется часто, я бы использовал option (recompile). Например:

SELECT * 
FROM YourTable 
WHERE col1 = @par1 AND col2 = @par2 AND ... 
OPTION (RECOMPILE) 

Это заставит планировщик запросов, чтобы воссоздать («перекомпилировать») план каждый раз, когда хранимая процедура называется. Учитывая низкую стоимость планирования (обычно ниже 25 мс), это разумное поведение для дорогостоящих запросов. Стоит 25 мс проверить, можете ли вы создать более разумный план для конкретных параметров для запроса 250 мс.

Если ваш запрос выполняется так часто, что стоимость планирования нетривиальна, вы можете использовать option (optimize for unknown). Это заставит SQL Server создать план, который, как ожидается, будет хорошо работать для всех значений всех параметров. Когда вы укажете этот параметр, SQL Server игнорирует первые значения параметров, поэтому это буквально предотвращает обнюхивание.

SELECT * 
FROM YourTable 
WHERE col1 = @par1 AND col2 = @par2 AND ... 
OPTION (OPTIMIZE FOR UNKNOWN) 

Этот вариант работает для всех параметров. Вы можете использовать optimize for (@par1 unknown), чтобы предотвратить обнюхивание только для одного параметра.

+7

Назначение параметров локальным переменным во избежание обнюхивания было стандартным обходным решением перед тем, как «ОПТИМИЗАЦИЯ ДЛЯ НЕИЗВЕСТНОГО» и флаг трассировки 4136 стал доступен. 'OPTION (RECOMPILE)' не отключает sniffing, он расширяет его, чтобы стать * встраиванием параметров *. Я знаю, что вы хотели сказать здесь, но это все еще не то, что вы на самом деле говорили. –

+0

@PaulWhite: Интересно, я предполагаю, что означает, что хранимая процедура анализируется за один раз вместо инструкции по выражению?Я обновлю ответ – Andomar

+0

Все партии сначала анализируются «одним движением» в один скомпилированный план (хотя и с вложенной структурой), включая хранимые процедуры, да. Рекомпиляция на уровне уровня была добавлена ​​в SQL Server 2005. –