我正在运行一个过程,第一次执行大约需要1分钟,而下一次它将减少到大约9-10秒。再过一段时间后,大约需要1分钟。
我的过程正在处理具有6个非聚集索引和1个聚集索引的单个表,唯一ID列是具有1,218,833行的uniqueidentifier数据类型。
您能指导我问题/可能的性能改进在哪里吗?
提前致谢。
这是步骤。
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
第一次运行查询时,数据不在数据高速缓存中,因此必须从磁盘中检索。此外,它还必须准备执行计划。随后,您运行查询时,数据将位于高速缓存中,因此不必进入磁盘即可读取数据。它还可以重用最初生成的执行计划。这意味着执行时间可能要快得多,这也是为什么理想的情况是拥有大量的RAM,以便能够在内存中尽可能多地缓存数据(数据缓存提供了最大的性能改进)。
如果执行时间随后再次增加,则有可能从缓存中删除数据(执行计划也可以从缓存中删除)-取决于对RAM的压力。如果SQL Server需要释放一些空间,它将从缓存中删除内容。最常使用/具有最高价值的数据/执行计划将保留更长的缓存时间。
当然,还有其他因素可能是一个因素,例如当时服务器上的负载,您的查询是否被其他进程阻止等。