日期范围查询方法的性能比较

时间:2012-02-17 13:52:44

标签: sql-server performance optimization

在下面的两个查询中,哪一个更快?该表包含超过100M条记录。所以我只想知道在where子句中使用ISNULL是否与首先为变量赋值并且仅使用where子句中的变量相同?

declare @dt datetime
select COUNT(*) from pandl 
  where PaymentDate >= ISNULL(@dt, convert(nvarchar(10),getdate(), 121))

select @dt = ISNULL(@dt, convert(nvarchar(10),getdate(), 121))
select COUNT(*) from pandl 
  where PaymentDate >= @dt

3 个答案:

答案 0 :(得分:2)

第二个会更好。从where子句调用函数将使查询优化器使用扫描而不是搜索。换句话说,你会得到一个不太理想的执行计划

答案 1 :(得分:2)

我建议采用稍微不同的方法,避免稍微更昂贵的转换为字符串,并使用稍小的数据类型来存储日期(因为如果你只关心日界,你不需要亚分钟的粒度):

DECLARE @dt SMALLDATETIME;
SET @dt = DATEADD(DAY, DATEDIFF(DAY, '19000101', CURRENT_TIMESTAMP), '19000101'); --*

SELECT COUNT(*) FROM dbo.pandl 
  WHERE PaymentDate >= @dt;

如果您要继续使用转换为字符串,请使用CHAR(10) - 我认为样式121不会产生任何需要Unicode支持的日期格式。

* 是的,您可以在没有外部 DATEADD 的情况下执行此操作,但不能使用 DATE等新类型

答案 2 :(得分:1)

FWIW,如果您没有索引,则不会影响该计划:

http://data.stackexchange.com/stackoverflow/query/61684/http-stackoverflow-com-questions-9329461-ms-sql-query-performance

以文本模式运行,检查show执行计划。

我认为StackExchange中的其中一个日期列会有一个索引,但我找不到。

除此之外,我对此有其他答案 - 不要不必要地使用nvarchar,不要没有充分理由将日期转换为字符串,不要使用可以在查询内部更可读地评估的函数一个查询(如果你不需要,不要在查询中使用函数)。