代价是不仅在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发布于 2011-06-02 18:37:47
我不认为你使用这两个中的哪一个无关紧要。执行计划也是一致的。
但是您似乎是在对列itsm_requiredbyx进行计算,然后检查结果是否在两个外部值@DateFrom和@DateTo之间。这样,该字段中的所有日期时间都由函数处理,然后才能应用WHERE条件,并且不能使用索引。@DOK答案中的第二个链接()提供了关于为什么以及何时发生这种情况的更详细的信息。
如果不对列进行任何计算,而是对外部值进行(反向)计算,然后检查itsm_requiredbyx是否在这两个计算值之间,则查询可以使用索引 itsm_requiredbyx (并且函数将只被调用两次,而不是针对表中的每一行)。
发布于 2011-06-02 17:57:01
This article可能会帮助您做出选择。如果对日期列进行了索引,则使用的方法之间可能会有很大的不同,特别是在WHERE子句中。
就像上面说的,
如果要搜索包含大量记录的大型表,则很可能会对一些通常用于约束查询的日期列进行索引。在WHERE子句中使用日期列时,如果日期列包装在函数中,则查询优化器将不使用索引。
这在Ten Common SQL Programming Mistakes中也有解释,特别是在#2对谓词中的索引列的函数下:
问题源于将索引列传递给函数,然后查询引擎必须为表中的每一行计算该函数。在这样的情况下,WHERE子句谓词被认为是“非SARGable的”,查询优化器所能做的最好的事情就是执行一个完整的索引或表扫描。
为了确保使用索引,我们需要避免在索引列上使用函数。
https://stackoverflow.com/questions/6212782
复制相似问题