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

Most optimal way to get all records IN previous month

以前我一直用:

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

这让我得到了上个月发生的所有记录。例如,如果我 运行 这个查询,它会得到一月份发生的所有记录。

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

WHERE [SettlementDate] >= DateAdd(DAY, -31, GETDATE())

它通常会在 10 秒内 运行。

我的问题是:
如何在不疯狂增加处理时间的情况下获得与 WHERE DATEDIFF(m, [DATE_COL], GETDATE()) = 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))

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

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 服务器会知道您想将 SettlementDate 值与日期进行比较,并且没有其他需要计算的东西。如果您在该列中有索引,它将使用该索引。

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