SQL Server存储过程比直接查询慢很多

时间:2012-10-22 04:47:24

标签: sql-server performance stored-procedures

我有一张超过100MM的记录表。该表具有聚簇索引和非聚簇索引。

我可以在表上使用T-SQL运行基本计数,运行需要1秒。当我在存储过程中放入相同的精确计数查询时,它需要12秒才能运行。

我已经查看了标准查询和存储过程的执行计划,他们都使用非聚集索引。

我不确定为什么存储过程与标准查询相比速度太慢。

我已经阅读过一些关于在这种情况下重新编制索引的内容,但我不确定为什么我需要这样做。此外,重新索引需要几个小时,所以我想确保它能够正常工作。

对此的任何帮助都会很棒。

由于

更新

这是存储过程:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE quickCount 

@sYID INT,
@eYID INT

AS
BEGIN

SET NOCOUNT ON;


    SELECT COUNT(leadID)
    FROM dbo.leads
    WHERE yearID >= @sYID
    AND yearID <= @eYID

END
GO

这是标准查询:

SELECT COUNT(leadID)
FROM leads
WHERE yearID >= 0
AND yearID <= 99

我确实尝试在没有参数的情况下运行它,SP运行速度更快(1秒)。所以我假设它与参数有关。

5 个答案:

答案 0 :(得分:16)

尝试将SP更改为使用传入的变量的本地副本。

这样的东西
ALTER PROCEDURE quickCount  

@sYID INT, 
@eYID INT 

AS 
BEGIN 

SET NOCOUNT ON; 
    DECLARE @Local_sYID INT, 
            @Local_eYID INT 
    SELECT  @Local_sYID = @sYID INT, 
            @Local_eYID = @eYID INT

    SELECT COUNT(leadID) 
    FROM dbo.leads 
    WHERE yearID >= @Local_sYID 
    AND yearID <= @Local_eYID 

END 

之前我发现由于参数Snffing,SP可以运行得慢很多,但是一旦你使用了变量副本,性能就会恢复。

What is Parameter Sniffing ?

SQL Server : Parameter Sniffing

答案 1 :(得分:4)

如前所述,这可能是参数嗅探问题。尝试包括以下行:

OPTION (RECOMPILE)

在SQL查询结束时。

这里有一篇文章解释了什么参数嗅探:http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx

答案 2 :(得分:1)

您总是可以尝试将其作为动态sql执行:

ALTER PROCEDURE quickCount  

@sYID INT, 
@eYID INT 

AS 
BEGIN 
    SET NOCOUNT ON;

    DECLARE @SQL VARCHAR(max)

    SELECT @SQL = '
    SELECT COUNT(leadID) 
    FROM dbo.leads 
    WHERE yearID >= '+CONVERT(VARCHAR(20),@sYID)+'
    AND yearID <=   '+CONVERT(VARCHAR(20),@eYID)

    EXEC (@SQL)
END 

答案 3 :(得分:0)

第一次运行存储过程时,SQL Server必须编译存储过程,这可能需要一些时间。 @Astander提到参数嗅探 - 这是一个有效的点,可能会扭曲你的结果。

要考虑的其他一些因素(虽然它们不应该真正解释您的症状):

  • 您可以强制锁定级别,例如在表名后面WITH (NOLOCK),可以解决问题(但请注意,这样做可能会得到不准确的结果)。
  • 您可能需要更新表中的统计信息或对索引进行碎片整理

答案 4 :(得分:0)

EXEC sp_recompile N'dbo.MyStoredProc';

帮了我大忙。存储的proc需要13秒才能运行,查询需要0.00秒。运行上述命令后,它们都需要0.00秒:)