获取上个月所有记录的最佳方式

时间:2017-02-10 22:48:04

标签: sql sql-server datediff

过去我一直使用:

WHERE DATEDIFF(m, [DATE_COL], GETDATE()) = 1

它获取了我在PREVIOUS月份发生的所有记录。例如,如果我运行此查询,它将获取1月份发生的所有记录。

但是我目前正在使用一个更大的表,如果我使用上面的查询,它需要将近30分钟才能加载。但是,如果我使用像

这样的东西
WHERE [SettlementDate] >= DateAdd(DAY, -31, GETDATE())

通常会在10秒内完成。

我的问题是:
如果没有处理时间的疯狂增加,我如何得到与WHERE DATEDIFF(m, [DATE_COL], GETDATE()) = 1相同的结果?

谢谢!

2 个答案:

答案 0 :(得分:1)

您的查询速度很慢,因为当您执行DATEDIFF(m, [DATE_COL], GETDATE())时,它无法使用[Date_Col]上的任何索引。

无论如何,您可以使用以下where子句,这将使用[SettlementDate]上的索引,并希望它应该比DATEDIFF()函数执行得更好。

WHERE [SettlementDate] >= DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE())-1, 0)  
AND [SettlementDate]  < DATEADD(DAY,1,DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1))

答案 1 :(得分:1)

问题是你有一个函数调用,查询优化器无法看到内部函数。这意味着,它无法决定是否使用索引。在这种情况下,它会读取整个表格,这可能需要很长时间。 我建议你使用变量,我相信你的查询会得到更好的结果:

declare @From datetime -- choose the same type as your SettlementDate column
set @From = DateAdd(DAY, -31, GETDATE()) -- compute the starting date
select * from yourTable where SettlementDate >= @From

在这种情况下,sql server会知道您要将SettlementDate值与日期进行比较,并且没有其他任何必须计算的内容。如果该列中有索引,则会使用该索引。

有关SARGable查询的其他信息:https://www.codeproject.com/Articles/827764/Sargable-query-in-SQL-server