2015-11-09 6 views
1

У меня есть хранимая процедура SQL Server, и она отлично работает на SQL Server 2008 R2.Хранимая процедура SQL Server 2012 работает медленно

Когда я пытаюсь запустить его на SQL Server 2012, для запуска требуется очень много времени.

Но если я создаю локальные переменные внутри хранимой процедуры и скопирую значения входных параметров в эти локальные переменные и использую их вместо входных параметров, запросы выполняются и возвращаются быстрее, чем в базе данных SQL Server 2008 R2 (обратите внимание на оба 2008 R2 и 2012 серверы работают в одном окне).

Не могли бы вы пролить свет на то, что здесь происходит?

+0

Должно быть на DBA.se, так как это не программирование вопрос. – cybermonkey

ответ

7

Создавая локальные переменные и значения пересвязывание отключить parameter sniffing:

нюхают

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

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

Run замедляется:

CREATE PROC [dbo].[DisplayBillingInfo] 
    @BeginDate DATETIME, 
    @EndDate DATETIME 
AS 
BEGIN 
    SELECT BillingDate, BillingAmt 
    FROM BillingInfo 
    WHERE BillingDate between @StartDate AND @StopDate; 
END 

Run быстро (потому что он должен рассчитать новый план каждый раз):

CREATE PROC [dbo].[DisplayBillingInfo] 
    @BeginDate DATETIME, 
    @EndDate DATETIME 
AS 
BEGIN 
    DECLARE @StartDate DATETIME = @BeginDate; 
    DECLARE @StopDate DATETIME = @EndDate; 

    SELECT BillingDate, BillingAmt 
    FROM BillingInfo 
    WHERE BillingDate between @StartDate AND @StopDate; 
END 

Дело оптимизатор SQL Server не может повторно использовать кешированный план и оценивать его каждый раз.

Это то же самое, как вы используете WITH RECOMPILE:

CREATE PROC [dbo].[DisplayBillingInfo] 
    @BeginDate DATETIME, 
    @EndDate DATETIME 
WITH RECOMPILE 
AS 
BEGIN 
    SELECT BillingDate, BillingAmt 
    FROM BillingInfo 
    WHERE BillingDate between @StartDate AND @StopDate; 
END 

используя подсказку запроса:

CREATE PROC [dbo].[DisplayBillingInfo] 
    @BeginDate DATETIME, 
    @EndDate DATETIME 
AS 
BEGIN 
    SELECT BillingDate, BillingAmt 
    FROM BillingInfo 
    WHERE BillingDate between @StartDate AND @StopDate 
    OPTION(RECOMPILE); 
    -- OPTION (OPTIMIZE FOR (@StartDate UNKNOWN, @StopDate UNKNOWN)) 
END 
+0

Thank you @ lad2025. Вы абсолютно правы в том, что мне нужно было сделать, чтобы запрос выполнялся быстро на SQL Server 2012. Но почему только на SQL-сервере 2012? Почему процедура отлично работает на SQL Server 2008? – kudlur

+0

@kudlur Возможно, в SQL Server 2008 у вас есть кешированный оптимальный план и параметры, которые хорошо работают с ним. Можете ли вы попробовать использовать другой параметр для воссоздания проблемы. Также, если вы сначала тестируете чистый буфер – lad2025

+0

SQL Server 2008 R2 является производством и до сих пор не сталкивался с проблемой медлительности. На SQL-сервере 2012 самое первое выполнение хранимой процедуры дало проблему. Падение и воссоздание не решило проблему. Опция перекомпиляции тоже не работала. – kudlur

Смежные вопросы