我在SQL Server表上有一个名为dd
的日期列。
dd
---------------------------
10-01-2015 00:00:00.000
22-05-2015 10:22:32.521
27-05-2015 12:30:48.310
24-12-2014 09:51:11.728
27-05-2015 02:05:40.775
....
我需要检索dd值来自过去24小时的所有行。
我找到了3个过滤选项以获得所需的结果:
1. `dd >= getdate() - 1`
2. `dd >= dateadd(day, -1, getdate())
3. `dateadd(day, 1, dd) >= getdate()
我的问题是: 所有3个选项都将检索我需要的所有行吗? 如果是这样,它们之间有什么区别?
答案 0 :(得分:7)
- 醇>
dd >= getdate() - 1
这就像黑客一样,但它确实有效,但有时会导致错误(http://www.devx.com/dbzone/Article/34594/0/page/2)。
- 的
醇>dd >= dateadd(day, -1, getdate())
强>
这是标准的做事方式。
- 醇>
dateadd(day, 1, dd) >= getdate()
这也可以,但有一个NO
。如果在该列上创建了任何索引,则不会使用索引。因为它不是Search Argument
(What makes a SQL statement sargable?)。当您将表达式应用于某个列时,它将变为非SARG
,并且不会使用任何索引。
所有3个版本都会产生相同的结果,但首先是黑客,在某些情况下会导致错误。第三个不会使用索引。所以显然应该坚持选项2。
答案 1 :(得分:4)
前两个与Giorgi完全一样,但在第三个上你的Index Seek将成为Index Scan。 SQL Server仍将使用该索引,但它不再能够跳转到特定记录,而是必须扫描它以找到它所需的内容。
出于演示的目的,我选择了DATETIME列已编制索引的表,并且仅选择该列以避免任何键查找,并保持计划简单。
另请参阅表格上的读数和估计的返回行数。只要在函数中包装列,就无法估计正确的行数,这会在查询变得更复杂时导致大的性能问题。