【问题标题】:Difference in performance in SQLSQL 中的性能差异
【发布时间】:2015-05-27 11:26:34
【问题描述】:

我在 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 个选项都将检索我需要的所有行吗?
如果有,它们之间有什么区别?

【问题讨论】:

  • #3 是你能做的最糟糕的事情!
  • 你看过执行计划了吗?
  • #1 和#2 是相同的,其中#1 只是MS-SQL 对#2 的简写符号。不过我会使用 #2,因为它似乎更清楚地向读者传达了正在添加的单元。
  • “我有一个日期栏...” 不,你没有。 date 列不能包含时间组件。您可能有一个datetime 列。

标签: sql-server performance datetime query-performance


【解决方案1】:
  1. dd >= getdate() - 1

这有点像 hack,但它确实有效,但有时会导致错误 (http://www.devx.com/dbzone/Article/34594/0/page/2)。

  1. dd >= dateadd(day, -1, getdate())

这是标准的做事方式。

  1. dateadd(day, 1, dd) >= getdate()

这也可以,但有一个NO。如果在该列上创建了任何索引,它将不会使用索引。因为它不是Search Argument(What makes a SQL statement sargable?)。当您将表达式应用于某个列时,它将变为非 SARG 并且不会使用任何索引。

所有 3 个版本都会产生相同的结果,但首先是 hack,在某些情况下会导致错误。第三不会使用索引。所以很明显,应该坚持选项 2。

【讨论】:

    【解决方案2】:

    前两个与 Giorgi 所说的完全一样,但在第三个中,您的 Index Seek 将变为 Index Scan。 SQL Server 仍将使用该索引,但它不再能够跳转到特定记录,而是必须扫描它以找到它需要的内容。

    出于演示的目的,我选择了索引 DATETIME 列的表,并且只选择了该列以避免任何键查找,并保持计划简单。

    还可以查看表上的读取以及估计与返回的行数。一旦您将列包装在函数中,它就无法估计正确的行数,当查询变得更加复杂时,这将导致大的性能问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-30
      • 1970-01-01
      • 2023-04-09
      • 2010-10-03
      • 1970-01-01
      • 2015-10-28
      • 2023-03-18
      • 1970-01-01
      相关资源
      最近更新 更多