【问题标题】:SQL Efficiency - Query using dateAdd Function twice; or SubQuery and DateAdd Function once; on Date BETWEENSQL 效率 - 使用 dateAdd 函数查询两次;或 SubQuery 和 DateAdd 函数一次;日期 BETWEEN
【发布时间】:2011-06-02 09:40:08
【问题描述】:

开销是不仅在 SELECT 中使用 DateAdd 函数,而且在 WHERE 中使用; 或者使用子查询,它最初返回的数据比我需要的多,但随后可以在不使用数据库的 DateAdd 函数的情况下进行过滤。

执行计划似乎暗示它们就其而言是相同的。 我想知道哪个更有效?

    DECLARE @DateFrom DateTime
    SET @DateFrom = '2011-05-27'
    DECLARE @DateTo DateTime
    SET @DateTo = '2011-06-27'

    SELECT id, name, 
    dateAdd(hour, datediff(hour, getdate(), getutcdate()), --UTC offset
            dateadd(second, itsm_requiredbyx, '1/1/1970 12:00 AM')) as itsm_requiredbyx
    FROM tablename
    WHERE dateAdd(hour, datediff(hour, getdate(), getutcdate()), --UTC offset
            dateadd(second, itsm_requiredbyx, '1/1/1970 12:00 AM'))
            BETWEEN @DateFrom AND @DateTo

    ORDER BY itsm_requiredbyx desc

    ---------------------------------------------------------------------------------------------

    SELECT *
    FROM
        (
        select id, name, 
        dateAdd(hour, datediff(hour, getdate(), getutcdate()), --UTC offset
                dateadd(second, itsm_requiredbyx, '1/1/1970 12:00 AM')) as itsm_requiredbyx
        from tablename 
        ) RR
    WHERE itsm_requiredbyx BETWEEN @DateFrom AND @DateTo
    ORDER BY itsm_requiredbyx desc

【问题讨论】:

  • 我认为这不重要。但您似乎正在对字段itsm_requiredbyx 进行计算,然后检查结果是否介于两个外部值@DateFrom@DateTo 之间。如果您不对字段进行任何计算,而是对外部值进行(反向)计算,然后检查itsm_requiredbyx 是否介于这两个计算值之间,则查询可以使用itsm_requiredbyx 的索引。
  • 有些语言环境与 UTC 的偏移量不是整数小时数。由于您似乎正在尝试编写国际代码,因此您可能需要注意这一点。

标签: sql sql-server performance tsql


【解决方案1】:

我认为你使用这两者中的哪一个并不重要。执行计划也同意。

但您似乎正在对列 itsm_requiredbyx 进行计算,然后检查结果是否介于两个外部值 @DateFrom@DateTo 之间。这样,该字段中的所有日期时间都由函数处理,然后才能应用 WHERE 条件并且不能使用索引。 @DOK 的回答中的第二个链接 (Ten Common SQL Programming Mistakes) 提供了有关发生这种情况的原因和时间的更详细信息。

如果您不对列进行任何计算,而是对外部值进行(反向)计算,然后检查 itsm_requiredbyx 是否介于这两个计算值之间,则查询可以使用 itsm_requiredbyx 的索引(并且这些函数只会被调用两次,而不是针对表中的每一行)。

【讨论】:

    【解决方案2】:

    This article 可能会帮助您选择。如果您的日期列已编入索引,则使用的方法可能会有很大差异,尤其是在 WHERE 子句中。

    正如它所说,

    如果您正在搜索包含大量记录的大型表,您很可能会索引一些通常用于限制查询的日期列。在 WHERE 子句中使用日期列时,如果日期列包含在函数中,则查询优化器将不会使用索引。

    Ten Common SQL Programming Mistakes 中也对此进行了解释,特别是在 #2 Functions on indexed columns on predicates 中:

    问题出在以下事实 索引列被传递给 查询引擎的一个函数 然后必须评估每一个 表中的行。在诸如 这些,WHERE 子句谓词是 被认为是“非SARGable”和最好的 查询优化器可以做的是 执行完整的索引或表扫描。

    为了确保索引被使用,我们 需要避免使用函数 索引列。

    【讨论】:

      猜你喜欢
      • 2021-11-15
      • 2021-11-26
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 2014-11-20
      • 2016-10-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多