Параметр Sniffing (или Spoofing) в SQL Server



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



пока все нормально.



хранимая процедура, однако, была медленной собакой. Нет существенной разницы между запросом и proc, но изменение скорости было массовым.



[фон, мы запускаем SQL Server 2005.]



дружелюбный местный DBA (который больше не работает здесь) взглянул на хранимую процедуру и сказал: "спуфинг параметров!"(Edit: хотя кажется, что это, возможно, также известно как "нюхание параметров", что может объяснить нехватку хитов Google, когда я пытался его найти.)



мы абстрагировали часть хранимой процедуры во вторую, обернули вызов этого нового внутреннего proc в уже существующий внешний, называемый внешним, и, Эй, престо, это было так же быстро, как и оригинал запрос.



Итак, что дает? Может кто-нибудь объяснить спуфинг параметров?



бонус за




  • подчеркивая, как этого избежать

  • предлагая, как распознать возможную причину

  • обсудите альтернативные стратегии, например, статистику, индексы, ключи, для смягчения ситуации

727   8  

8 ответов:

FYI-вы должны быть осведомлены о чем-то еще, когда вы работаете с SQL 2005 и храните procs с параметрами.

среда SQL Server будет составить план выполнения хранимой proc и с первым параметром, который используется. Так что если вы запустите это:

usp_QueryMyDataByState 'Rhode Island'

план выполнения будет работать с данными небольшого государства. Но если кто-то оборачивается и бежит:

usp_QueryMyDataByState 'Texas'

план выполнения, разработанный для данных размера Род-Айленда, может быть не столь эффективным с помощью Данные размером с Техас. Это может привести к неожиданным результатам при перезапуске сервера, потому что вновь созданный план выполнения будет нацелен на любой параметр, который используется в первую очередь - не обязательно лучший. План не будет перекомпилирован, пока не будет большой причины для этого, например, если статистика будет перестроена.

здесь появляются планы запросов, и SQL Server 2008 предлагает множество новых функций, которые помогают DBAs закрепить конкретный план запроса на месте в долгосрочной перспективе независимо от того, что сначала вызываются параметры.

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

Да, я думаю, что вы имеете в виду обнюхивание параметров, которое является методом, который оптимизатор SQL Server использует, чтобы попытаться выяснить значения/диапазоны параметров, чтобы он мог выбрать лучший план выполнения для вашего запроса. В некоторых случаях SQL Server плохо справляется с параметром sniffing и не выбирает лучший план выполнения для запроса.

Я считаю, что эта статья в блогеhttp://blogs.msdn.com/queryoptteam/archive/2006/03/31/565991.aspx имеет хорошее объяснение.

Это кажется, что дБА в своем примере выбрал вариант № 4 запрос на другой sproc отдельного процессуального контексте.

вы могли бы также использовать С перекомпиляция на оригинальном sproc или использовал оптимизация опция на параметре.

простой способ ускорить это-переназначить входные параметры локальным параметрам в самом начале sproc, например

CREATE PROCEDURE uspParameterSniffingAvoidance
    @SniffedFormalParameter int
AS
BEGIN

    DECLARE @SniffAvoidingLocalParameter int
    SET @SniffAvoidingLocalParameter = @SniffedFormalParameter

    --Work w/ @SniffAvoidingLocalParameter in sproc body 
    -- ...

по моему опыту, лучшим решением для обнюхивания параметров является "динамический SQL". Две важные вещи, чтобы отметить, что 1. вы должны использовать параметры в динамическом sql-запросе 2. вы должны использовать sp_executesql (а не sp_execute), который сохраняет план выполнения для каждого значения параметра

обнюхивание параметров-это метод, который SQL Server использует для оптимизации плана выполнения запроса для хранимой процедуры. При первом вызове хранимой процедуры SQL Server просматривает заданные значения параметров вызова и решает, какие индексы использовать на основе значений параметров.

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

вы можете обойти это либо

  • используя WITH RECOMPILE
  • копирование значений параметров в локальные переменные внутри хранимой процедуры и использование локальных значений в запросах.

Я даже слышал, что лучше вообще не использовать хранимые процедуры, а отправлять свои запросы непосредственно на сервер. Недавно я столкнулся с той же проблемой, где у меня еще нет реального решения. Для некоторых запросов помогает копирование в локальные vars возвращаясь к правильному плану выполнения, для некоторых запросов производительность ухудшается с локальными vars.

Мне все еще нужно провести дополнительные исследования о том, как SQL Server кэширует и повторно использует (неоптимальные) планы выполнения.

У меня была аналогичная проблема. План выполнения моей хранимой процедуры уходило 30-40 секунд. Я попытался использовать инструкции SP в окне запроса, и для их выполнения потребовалось несколько МС. Затем я разработал объявление локальных переменных в хранимой процедуре и перенос значений параметров в локальные переменные. Это сделало выполнение SP очень быстрым, и теперь тот же SP выполняется в течение нескольких миллисекунд вместо 30-40 секунд.

очень простой и сортировать, оптимизатор запросов использовать старый план запроса для часто выполняемых запросов. но на самом деле размер данных также увеличивается, поэтому в это время требуется новый оптимизированный план и все еще оптимизатор запросов, использующий старый план запроса. Это называется параметрическим обнюхиванием. Я напишу подробный пост об этом. Пожалуйста, посетите этот url: http://www.dbrnd.com/2015/05/sql-server-parameter-sniffing/

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

пакетный файл выберите именно:

exec ('select * from order where  order id ='''+ @ordersID')

вместо обычной хранимой процедуры выберите:

select * from order where  order id = @ordersID

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

Comments

    Ничего не найдено.