这两个查询在逻辑上是否等效?


10

这两个查询在逻辑上是否等效?

DECLARE @DateTime DATETIME = GETDATE()

查询1

SELECT *
FROM   MyTable
WHERE  Datediff(DAY, LogInsertTime, @DateTime) > 7   

查询2

SELECT *
FROM   MyTable
WHERE  LogInsertTime < @DateTime - 7 

如果它们在逻辑上不是等效的,您可以给我第一个查询的逻辑等效,以便WHERE子句可以有效地使用索引(即消除函数包装)吗?


什么类型LogInsertTime
dezso 2012年


LogInsertTime是DATETIME
Alf47

Answers:


15

您发布的两个查询在逻辑上是否相等并不重要;您不应该使用它们中的任何一个。我会尽量避免您采取以下行动:

  1. 尽可能避免将函数应用于列。始终将这些计算与常量而不是列相对应,这总是一样好,而且通常更好,这可能会破坏SARGability并使这些列上的索引无用。在这种情况下,我更喜欢查询2,尤其是如果LogDateTime已对索引2 进行了索引(或者可能对其进行了索引)。
  2. 我不喜欢速记数学,因此建议不要这样做。当然,键入速度更快,但是尝试使用DATE数据类型进行输入,您将得到一个难看的错误。更好地说明它,例如:

    WHERE LogInsertTime < DATEADD(DAY, -7, @DateTime);

我同意,我的目标是将查询1更改为类似于查询2的内容,以便可以有效地使用索引。谢谢您的帮助
-Alf47

8

我将使用以下可查询查询:

SELECT * FROM MyTable WHERE LogInsertTime < DATEADD(DAY, -7, @DateTime)

原因:我认为@ DateTime-7的结果没有记录。即使它恰好等于DATEADD(DAY,-7,@DateTime),它也可能在以后的版本中中断。


太好了,这正是我一直在寻找的东西,谢谢
Alf47

2
实际上,它已被记录且定义明确::- (Subtract): Subtracts two numbers (an arithmetic subtraction operator). Can also subtract a number, in days, from a date.。不过,我同意使用显式日期函数使结果查询比“算术运算符魔术”更具可读性和可维护性。
海因兹

6

它们不是等效的。7天前但一天中当前时间之前的记录 -仅在查询2中返回:

使用DATEADD功能比较天数时,不会考虑时间部分。无论何时比较星期日和星期一,该函数都将返回1。

演示:

DECLARE @MyTable TABLE(pk INT, LogInsertTime DATETIME);

INSERT @MyTable
VALUES (1, DATEADD(HOUR, 1, CAST(DATEADD(DAY, -7, CAST (GETDATE() AS DATE))AS DATETIME))),
(2, DATEADD(HOUR, 23, CAST(DATEADD(DAY, -7, CAST (GETDATE() AS DATE)) AS DATETIME)));

DECLARE @DateTime DATETIME = GETDATE();

SELECT *
FROM @MyTable
WHERE DATEDIFF(DAY, LogInsertTime, @DateTime) > 7;

-- 0 records.

SELECT *
FROM @MyTable
WHERE LogInsertTime < @DateTime - 7;
-- 1 record.

第一个查询的逻辑上的等效关系将使潜在的索引使用成为可能,即删除其中的时间部分@DateTime或将时间设置为0:00:00

SELECT *
FROM @MyTable
WHERE LogInsertTime < CAST(@DateTime - 7 AS DATE);

第一个查询不能在其上使用索引LogInsertTime的原因是因为该列埋在函数内。查询2将列与常量值进行比较,以使优化程序可以选择上的索引LogInsertTime

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.