【问题标题】:Is SQL 'clever enough' to optimise out a NULL check in a simple where?SQL“足够聪明”可以在一个简单的地方优化空检查吗?
【发布时间】:2016-02-04 17:55:03
【问题描述】:

诚然,标题可能有点混乱,所以我先举个例子。

我有一个包含大量数据的表。我将一个日期传递给一个存储过程,该存储过程将用作相当标准的select 上的where 的一部分:

@MinDate DATETIME

SELECT *
FROM   MyTable
WHERE  (@MinDate IS NULL OR DatePublished >= @MinDate)

这很好用,但是数据库是否会为每条记录评估@MinDate?即它是否击中where 并且必须每次都检查null?如果是这样,将其重构为:

@MinDate DATETIME

IF(@MinDate IS NULL)
   SELECT *
   FROM   MyTable
ELSE
   SELECT *
   FROM   MyTable
   WHERE  DatePublished >= @MinDate

编辑:请忽略一些小的语法错误,为了简单起见,我已经断章取义了。我问的前提还是很清楚的。

【问题讨论】:

  • 只需在提供 MinDate 和 NULL 的情况下首先检查执行计划。无论如何,您的问题是关于 short-circuit evaluation
  • 答案取决于使用的 dbms。标记您正在使用的那个。
  • 这里存在潜在的性能问题。我使用OPTION(RECOMPILE) 进行此类查询。阅读 Erland Sommarskog 的 Dynamic Search Conditions in T‑SQL 了解详细信息和其他处理方法。

标签: sql select null where sql-server-2014


【解决方案1】:

SQL 既不聪明也不笨拙。它是 DBMS 的查询优化器。一般来说,优化器非常聪明,否则 SQL 几乎没有用处。 优化器努力避免查看每一行。

因此,希望您的 DBMS 对其进行优化。即使不是,我希望这不是您的应用程序的性能瓶颈。您只需确保在DatePublished 上有一个索引。

如果您想确定,请查看您的 DBMS 的文档,了解如何检查“执行计划”或如何在 DBMS 进行全表扫描时记录。

【讨论】:

    【解决方案2】:

    SQL Server 确实在其索引和统计信息中包含空值,但它是否有用取决于列的选择性。如果您有很多空值,那么进行扫描可能比寻找更有效,因为您最终会阅读相同或更多的页面。

    所以是的,SQL Server 会尝试为您的查询生成一个有效的计划,但它最终会做什么取决于数据和可用索引(如果启用,它还可以自动构建统计信息)。通过查看查询计划很容易验证。

    顺便说一句,您的第二个查询返回的结果与第一个查询不同(有效的 TSQL 语法不受约束)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-09
      • 1970-01-01
      • 2023-02-09
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多