带有时间戳和变量的SQL Server查询性能

时间:2015-06-15 20:20:57

标签: sql-server performance timestamp

我有一个简单的SQL查询来计算过去24小时内客户的遥测记录数。

使用TimeStamp上的索引,对于大约10k行,以下查询在不到1秒的时间内运行

select MachineName,count(Message) from Telemetry where TimeStamp between DATEADD(HOUR,-24, getutcdate()) and getutcdate() group by MachineName

但是,当我尝试使硬编码-24可配置并添加变量时,查询执行的时间超过5分钟。

DECLARE @cutoff int; SET @cutoff = 24

select MachineName,count(Message) from Telemetry where TimeStamp between DATEADD(HOUR, -1*@cutoff, getutcdate()) and getutcdate() group by MachineName

性能显着下降是否有任何具体原因?在不影响性能的情况下添加变量的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

我的猜测是你还有一个关于MachineName的索引 - 或者SQL正在决定,因为它需要按MachineName分组,这将是访问记录的更好方法。

按照AngularRat的建议更新统计信息是一个很好的开始 - 但SQL通常会自动维护这些。 (事实上​​,当SQL知道提前24小时间隔的良好性能证明统计数据是好的......但是当SQL不提前知道BETWEEN的大小时,然后它认为其他方法可能是一个更好的主意。)

假设:

CREATE TABLE Telemetry  ( machineName sysname, message varchar(88), [timestamp] timestamp)
CREATE INDEX Telemetry_TS ON Telemetry([timestamp]);

首先,尝试使用OPTION (OPTIMIZE FOR ( @cutoff = 24 ));子句让SQL知道如何处理查询,如果不够,请尝试WITH (Index( Telemetry_TS))。使用INDEX提示是不太可取的。

DECLARE @cutoff int = 24;
select MachineName,count(Message) 
from Telemetry  -- WITH (Index( Telemetry_TS))
where TimeStamp between DATEADD(HOUR, -1*@cutoff, getutcdate()) and getutcdate() 
group by MachineName
OPTION (OPTIMIZE FOR ( @cutoff = 24 )); 

答案 1 :(得分:0)

您的参数应该可以正常工作,但您可能会看到数据库使用查询计划的过期统计信息的问题。我会尝试更新您正在查询的表的统计信息。类似的东西:

UPDATE STATISTICS TableName;

此外,如果您的代码是在存储过程中运行的,则可能需要重新编译该过程。类似的东西:

EXEC sp_recompile N'ProcedureName';

很多时候,如果我的查询看起来应该运行得快得多,但事实并非如此,这是一个过时的统计/查询计划问题。

参考文献:

https://msdn.microsoft.com/en-us/library/ms187348.aspx

https://msdn.microsoft.com/en-us/library/ms190439.aspx