简体   繁体   English

查询运行速度快,存储过程慢-尝试了多种操作

[英]Query Runs Fast, Stored Procedure Slow - Multiple things tried

I have a stored procedure on SQL Server 2014 and when running the query directly with the params hard coded, it runs instantly. 我在SQL Server 2014上有一个存储过程,当使用硬编码的参数直接运行查询时,它会立即运行。 When its run through the stored procedure it takes a long time or times out. 当它通过存储过程运行时,将花费很长时间或超时。

It appears the parameters in the select query where its getting the top 1 在选择查询中显示参数,该参数排在前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' )

that is causing the problems as I have hardcoded these params in the stored procedure and it runs almost instantly. 这是导致问题的原因,因为我已经在存储过程中对这些参数进行了硬编码,并且它几乎立即运行。

I have read a lot about parameter sniffing and as suggested in Query runs fast, but runs slow in stored procedure and have tried a few things; 我已经阅读了很多有关参数嗅探的知识,并且正如Query中所建议的那样, 运行速度很快,但是在存储过程中运行速度却很慢,并且尝试了一些方法。 I have made the parameters local ones I have also tried adding the 我已经将参数设为本地参数,也尝试添加

OPTION(RECOMPILE)

and tried running 并尝试运行

exec sp_updatestats 

but all appeared to make either no or very little difference. 但似乎一切都没有或几乎没有什么不同。

The stored procedure is as follows: 存储过程如下:

     @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 @local_userName=@userName, @local_orgId=@orgId,@local_chartId=@chartId /*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

SQL Server does do a good job for the most part with implicit casts, but there are times that it can bog a query down. SQL Server在大多数情况下都使用隐式强制转换做得很好,但是有时它可能会使查询陷入瘫痪。 You mentioned that hard-coding the values returns instantly, but using a variable does not. 您提到对值进行硬编码会立即返回,但使用变量却不会。

When using a variable, make sure that the datatype matches the column's datatype. 使用变量时,请确保数据类型与列的数据类型匹配。 I suspect that the issue is that your variables are NVARCHAR (100) whilst your columns are VARCHAR (50) . 我怀疑问题是您的变量是NVARCHAR (100)而列是VARCHAR (50)

Another way to see if this might be an issue is by looking at the query plan - in such a case, you might see something similar to the following as a warning: 查看这是否可能是问题的另一种方法是查看查询计划-在这种情况下,您可能会看到类似以下内容的警告:

Type conversion in expression (CONVERT_IMPLICIT(...)) may affect "SeekPlan" in query plan choice 表达式中的类型转换(CONVERT_IMPLICIT(...))可能会影响查询计划选择中的“ SeekPlan”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM