Хранимая процедура выполнения - это WILD? - PullRequest
5 голосов
/ 05 декабря 2011

Этот вопрос не столько в поиске решения, сколько в объяснении странного поведения, которое я когда-либо видел в SQL Server.

У меня была хранимая процедура со следующей подписью:

alter procedure MySP @param1 uniqueidentifier, 
                     @param2 uniqueidentifier, 
                     @param3 uniqueidentifier

Учитывая определенный набор параметров, этот процесс занимал очень много времени для запуска из C # (используя SqlCommand.ExecuteReader()) - около 2 минут. Используя те же параметры в сеансе прямого запроса, SP запускался менее чем за 2 секунды.

Это заняло много времени, и я даже не буду пытаться объяснить, как мы наткнулись на это решение, но вот что мы сделали:

В начале SP мы объявили 3 локальные переменные и присвоили их значениям параметров, например:

declare @param1_copy uniqueidentifier, 
        @param2_copy uniqueidentifier, 
        @param3_copy uniqueidentifier

select @param1_copy = @param1,
       @param2_copy = @param2,
       @param3_copy = @param3

А затем в остальной части SP мы заменили все ссылки на входные параметры локальными копиями.

Вуаля. SP выполняется менее чем за 2 секунды. И команда здесь ошеломлена.

Теперь, дамы и господа, кто-нибудь может объяснить это поведение?

Ответы [ 3 ]

8 голосов
/ 05 декабря 2011

Это звучит как нюхание параметров .

Из определения Microsoft:

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

Похоже, вы уже выяснили одно исправление, другое - использовать EXEC... WITH RECOMPILE:

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

3 голосов
/ 05 декабря 2011

Предлагаю прочитать отличную статью Эрланда Соммарского: Медленно в приложении, быстро в SSMS? Понимание загадок производительности .

В нем есть полная информация по этому вопросу.

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

0 голосов
/ 05 декабря 2011

У меня была похожая ситуация, когда у меня был параметр типа xml, и для его выполнения требовалось много времени.Я сделал тот же подход и создал локальную переменную и передал значение параметра, и он работал очень быстро:)

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

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