与下次运行相比,sql 查询需要很长时间

Posted

技术标签:

【中文标题】与下次运行相比,sql 查询需要很长时间【英文标题】:sql query takes much long time compared to next run 【发布时间】:2010-10-29 07:45:57 【问题描述】:

我正在运行一个程序,第一次执行大约需要 1 分钟,但下一次它会减少到大约 9-10 秒。一段时间后,大约需要 1 分钟。

我的程序正在处理具有 6 个非聚集索引和 1 个聚集索引的单个表,并且唯一 id 列是具有 1,218,833 行的唯一标识符数据类型。

你能指导我哪里有问题/可能的性能改进吗?

提前致谢。

这是程序。

 PROCEDURE [dbo].[Proc] (
        @HLevel NVARCHAR(100),
        @HLevelValue INT,
        @Date DATE,
        @Numbers NVARCHAR(MAX)=NULL
    )
    AS 

    declare   @LoopCount INT ,@DateLastYear DATE 


    DECLARE @Table1 TABLE ( list of columns )
    DECLARE @Table2 TABLE ( list of columns )

    -- LOOP FOR 12 MONTH DATA
    SET @LoopCount=12
    WHILE(@LoopCount>0)
        BEGIN
            SET @LoopCount= @LoopCount -1 

            -- LAST YEAR DATA
            DECLARE @LastDate DATE;
            SET @LastDate=DATEADD(D,-1, DATEADD(yy,-1, DATEADD(D,1,@Date)))




                    INSERT INTO @Table1  
                    SELECT list of columns 
                        FROM Table3 WHERE  Date = @Date   
                    AND 
                    CASE 
                        WHEN @HLevel='crieteria1' THEN col1
                        WHEN @HLevel='crieteria2' THEN col2
                        WHEN @HLevel='crieteria3' THEN col3
                    END =@HLevelValue



                    INSERT INTO @Table2 
                        SELECT list of columns 
                        FROM table4
                        WHERE  Date= @LastDate 
                         AND ( @Numbers IS NULL OR columnNumber IN ( SELECT *  FROM dbo.ConvertNumbersToTable(@Numbers)))

INSERT INTO @Table1
        SELECT list of columns 
            FROM @Table2 Prf2 WHERE Prf2.col1 IN (SELECT col2  FROM @Table1) AND Year(Date) = Year(@Date)



   SET @Date = DATEADD(D,-1,DATEADD(m,-1, DATEADD(D,1,@Date)));

 END 

  SELECT list of columns FROM @Table1

【问题讨论】:

您是否尝试过使用执行计划来让您了解查询发生了什么?另外,第一次运行时,它会将执行计划缓存在内存中,以便下次执行更快。 请显示一些代码,以便我们看看你在做什么。 有什么办法可以手动添加执行计划来加快速度,而且会一直存在。 你不能强迫它永远存在,因为 SQL Server 可能会删除它。此外,提供最大改进的不是执行计划缓存,而是缓存数据。同样,SQL Server 可以在一段时间后从缓存中删除内容。 【参考方案1】:

第一次运行查询时,数据不在数据缓存中,因此必须从磁盘中检索。此外,它必须准备一个执行计划。随后运行查询时,数据将在缓存中,因此不必去磁盘读取它。它还可以重用最初生成的执行计划。这意味着执行时间可以更快,为什么理想的情况是拥有大量 RAM 以便能够在内存中缓存尽可能多的数据(数据缓存提供了最大的性能改进)。

如果随后执行时间再次增加,则可能会从缓存中删除数据(并且也可以从缓存中删除执行计划) - 取决于 RAM 的压力。如果 SQL Server 需要释放一些东西,它会从缓存中删除一些东西。最常使用/具有最高值的数据/执行计划将保持缓存更长时间。

当然还有其他因素可能是一个因素,例如当时服务器上的负载,您的查询是否被其他进程阻止等

【讨论】:

一些猜测。在第一次执行后运行 \\ CHECKPOINT \\ DBCC DROPCLEANBUFFERS() \\ 。如果后续执行仍然很慢,那么 AdaTheDev 就在现场。是缓存。因此,如果目标是让查询在所有情况下都能快速运行,则需要更多信息。 @Chingi - 你可以用这个过程做的最好的事情是重写它以摆脱循环。如果您想要获得良好的性能,通常应避免使用循环/游标。【参考方案2】:

似乎存储过程在一段时间后重复重新编译。为了减少重新编译,请查看这篇文章:

http://blog.sqlauthority.com/2010/02/18/sql-server-plan-recompilation-and-reduce-recompilation-performance-tuning/

【讨论】:

以上是关于与下次运行相比,sql 查询需要很长时间的主要内容,如果未能解决你的问题,请参考以下文章

SQL 查询运行了很长时间

为啥 SQL Server 表值函数插入需要很长时间?

SQL 调优,长时间运行的查询 + rownum

用于从表中获取记录的 SQL 查询需要很长时间,但是当我运行 exec sp_updatestats 时按预期工作

odbc_exec 执行简单查询需要很长时间

服务器重启后首次运行大表查询需要很长时间