2016-12-13 2 views
0

У меня есть хранимая процедура на SQL Server 2014 и при запуске запроса напрямую с параметрами жестко закодирована, она запускается мгновенно. При прохождении через хранимую процедуру требуется много времени или времени.Query Runs Fast, Stored Procedure Slow - Несколько попыток

Оказывается параметры в запросе на выборке, где ее получение топа 1

, ISNULL((SELECT TOP 1 block_score FROM block_states BS WHERE BS.block_id = defined_blocks.id AND BS.user_name = @local_userName AND BS.orgId = @local_orgId AND BS.assessment_key = 0), 'NONE') 

, который вызывает проблемы, как я зашит этот Params в хранимой процедуре, и она работает почти мгновенно.

Я много читал о parameter sniffing и, как предложено в Query runs fast, but runs slow in stored procedure, и попробовал несколько вещей; Я сделал параметры локальные Я также попытался добавить

OPTION(RECOMPILE) 

и попытался запустить

exec sp_updatestats 

, но все оказалось сделать либо нет или очень мало разницы.

Хранимая процедура выглядит следующим образом:

 @userName NVARCHAR(100), @orgId NVARCHAR(100),@ chartId INT 
AS 



    DECLARE @definedchartBlocks TABLE(
     chartId INT, 
     sectId BIGINT, 
     subsectId BIGINT, 
     blockId BIGINT, 
     blockScore NVARCHAR(10) 

    ) 
     Declare @local_userName NVARCHAR(100), @local_orgId NVARCHAR(100), @local_chartId INT 
     select @[email protected], @[email protected],@[email protected] /*attempt to speed up stp*/ 


    INSERT INTO @definedchartBlocks 

    SELECT  
     defined_sects.chart_id 
     , defined_subsects.sect_id 
     , defined_blocks.subsect_id 
     , defined_blocks.id AS blockId 

     , ISNULL((SELECT TOP 1 block_score FROM block_states BS WHERE BS.block_id = defined_blocks.id AND BS.user_name = @local_userName AND BS.orgId = @local_orgId AND BS.assessment_key = 0), 'NONE') 
    FROM   
     defined_subsects 
     INNER JOIN 
     defined_sects ON defined_subsects.sect_id = defined_sects.id 
     INNER JOIN 
     defined_blocks ON defined_subsects.id = defined_blocks.subsect_id 
    WHERE  
     (defined_sects.chart_id = @local_chartId) 

OPTION(RECOMPILE) 

    IF EXISTS (
    SELECT  
      MAX(definedchartBlocks.blockScore) 
    FROM   
     @definedchartBlocks definedchartBlocks 
    WHERE 
     definedchartBlocks.blockScore = 'AMBER' OR definedchartBlocks.blockScore = 'RED' OR definedchartBlocks.blockScore = 'NONE' OR definedchartBlocks.blockScore = '' OR definedchartBlocks.blockScore IS NULL 

    GROUP BY 
     definedchartBlocks.blockScore 
    ) 
    BEGIN 

     SELECT 0 AS chartCompleted 
    END 
    ELSE 
    BEGIN 
     SELECT 1 AS chartCompleted 
    END 
+0

Являются ли столбцы 'username' и' orgid' 'NVARCHAR (100)' datatypes? – Siyual

+0

@ Siyual - На самом деле, нет, они не являются варчаром (50). Я не думал проверять это, это унаследованная хранимая процедура. Я сравню их, а затем попробую. – Bex

+0

@ Siyual, который работал! Спасибо!! Положите это как ответ, чтобы я мог дать вам кредит, которого вы заслуживаете! – Bex

ответ

4

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

При использовании переменной убедитесь, что тип данных соответствует типу столбца. Я подозреваю, что проблема в том, что ваши переменные - NVARCHAR (100), а ваши столбцы - VARCHAR (50).

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

типа в выражении (CONVERT_IMPLICIT (...)) может повлиять на «SeekPlan» в выборе плана запроса.

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