2010-10-25 165 views
3

已经创建了一个用于监控网站的存储过程。第一次运行时存储过程执行缓慢

第一次运行时,程序需要一分钟才能执行,如果在此之后运行,只需几秒钟即可运行。问题在于脚本计划以10分钟的间隔运行,并且每次运行脚本都需要花费一分多钟,时间太长。

是否有人知道我们如何提高此查询的性能?我知道有一个原因是它第一次运行缓慢,然后很快就会发生,但一直未能找到答案。

下面的代码,在此先感谢:)

SET NOCOUNT ON 
SET DATEFORMAT ymd 

declare @start datetime 
declare @end datetime 
set @start = DATEADD(dd,-1,GETDATE()) 
set @end = GETDATE() 

declare @errorToday int 
declare @unconfirmedToday int 

set @unconfirmedToday = 
(
SELECT COUNT([DateCreated]) 
FROM GenericLeadLogs WITH(NOLOCK) 
WHERE DestinationConfirmation IS NULL 
AND [DateCreated] BETWEEN @start AND @end 
) 

SET @errorToday = 
(
SELECT COUNT([DateCreated]) 
FROM GenericLeadLogs WITH(NOLOCK) 
WHERE Severity = 'Error' 
AND [DateCreated] BETWEEN @start AND @end 
) 

CREATE TABLE #GenericLeadStats 
(
UnconfirmedToday int null, 
ErrorToday int null 
) 

INSERT INTO #GenericLeadStats (UnconfirmedToday, ErrorToday) 
values(@unconfirmedToday, @errorToday) 

SELECT * FROM #GenericLeadStats 
DROP TABLE #GenericLeadStats 
+1

只是好奇 - 为什么你最后的东西w /临时表?为什么不选择你的两个变量 - 选择@unconfirmedToday作为UnconfirmedToday,@errorToday作为ErrorToday – 2010-10-25 01:43:26

回答

4

我重新写存储过程为:

SET NOCOUNT ON 

SELECT SUM(CASE WHEN DestinationConfirmation IS NULL THEN 1 ELSE 0 END) AS unconfirmedToday, 
     SUM(CASE WHEN Severity = 'Error' THEN 1 ELSE 0 END) AS errorToday 
    INTO #GenericLeadStats 
    FROM GenericLeadLogs WITH(NOLOCK) 
WHERE [DateCreated] BETWEEN DATEADD(dd,-1,GETDATE()) AND GETDATE() 

SELECT * FROM #GenericLeadStats 

DROP TABLE #GenericLeadStats 

在SQL Server中,SELECT INTO子句创建一个不存在的表。我要离开它,但它根据提供的内容没有任何用处。

+2

此外请注意,此查询将更好地使用DateCreated上的索引(甚至更好,如果该索引包括DestinationConfirmation和Severity)。由于OMG, – 2010-10-25 01:45:12

+0

运行得更快。不确定为什么我不认为结合以前的选择语句! – timothyclifford 2010-10-26 00:05:49

2

一般来说,数据库存储在磁盘上。但是,在所有现代操作系统上,读取后的文件通常会缓存在内存中。查询运行缓慢的原因是数据正在从磁盘读取。在第一次查询之后,大部分重新执行查询所需的数据(如果不是全部的话)被缓存,并且不需要实际从磁盘读取(慢)。经过一段时间后,如果机器用于其他目的或者其他查询运行,数据将从缓存中移出以为新数据腾出空间,因此只要数据需要重新读取,查询就会再次变慢从磁盘。

你应该确定在上面的语句中的所有列上都有一个索引。我假设完成了?如果是这样,那么请检查查询计划以查看它们是否正在使用。最后,如果表格非常大,如果在数据模型中有意义,可以考虑对其进行分区。

1

看着你的查询,我看不到任何明显的错误,会导致巨大的性能问题 - 第二次查询更快的原因很可能仅仅是因为所需的数据仍然被缓存,其中如果没有太多的事情可以做。

您应该获得一个执行计划,并可能通过查询优化器运行您的查询以查看是否缺少任何索引 - 如果缺少任何索引,这可能有助于提高查询的性能。