SQL效率 - 使用dateAdd函数查询两次;或SubQuery和DateAdd函数一次;在BETWEEN的日期

时间:2011-06-02 09:40:09

标签: sql sql-server performance tsql

费用不仅在SELECT中使用DateAdd函数,还在WHERE中使用; 或者使用Sub Query,它最初会返回比我需要的更多的数据,但是可以在数据库上再次使用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

2 个答案:

答案 0 :(得分:7)

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

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

如果您不对列进行任何计算,但是您对外部值执行(反向)计算,然后检查itsm_requiredbyx是否在这两个计算值之间,则查询可以使用< itsm_requiredbyx的strong> index (函数只会被调用两次而不是表中的每一行。)

答案 1 :(得分:1)

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

正如它所说,

  

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

这在Ten Common SQL Programming Mistakes中也有解释,特别是在谓词中索引列的#2函数下:

  

问题来自于这样的事实   索引列正在传递给   一个函数,它是查询引擎   然后必须评估每一个   在表中排。在诸如此类的情况下   这些,WHERE子句谓词是   被视为“非SARGable”并且是最好的   查询优化器可以做的是   执行完整的索引或表扫描。

     

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