我执行了一个SQL查询,我必须在FromDate和ToDate之间选择数据。
早些时候我使用了DATEDIFF
功能,完成时间约为8秒。但是当我用BETWEEN condition (..WHERE TranDate BETWEEN @FromDate AND ToDate);
执行相同的查询时,它立刻执行了。
这可能是什么原因?
答案 0 :(得分:0)
很难用这么少的关于您的数据库架构和查询的信息来回答这个问题,但我会试一试。
您的2个查询之间的区别在于,第一个查询(DATEDIFF
)不是sargable,而第二个(使用BETWEEN
是可搜索的)。这是评论中提到的dnoeth。
为什么重要?因为,正如维基百科所说:
在关系数据库中,查询中的条件被认为是可搜索的 如果DBMS引擎可以利用索引来加速 执行查询。
好的,所以现在我们明白,因为你可以利用索引,所以可以做到很好。但接下来的问题是:为什么索引很重要,为什么DATEDIFF不会被抨击?
首先,如果您不知道索引是什么,我建议您查看here。
在这里,我将使用sqlserver doc on DATEDIFF,因此第一个参数是startdate,第二个参数是结束日期。另外,我假设您构建了这样的查询,foo_date是您要检查的行的日期:(DATEDIFF(FromDate, foo_date) > 0) AND (DATEDIFF(foo_date, ToDate) >0)
为什么这不可思议?因为索引的是foo_date的值,而没有函数的结果。
我们举一个例子。你是你的SQL服务器。您想要查找符合条件的所有行。并且您的foo_date字段已编入索引,因此您有一个foo_date的有序列表。
我们告诉你BETWEEN FromDate AND ToDate
。嗯,这很容易,你看中间(在你的索引中),你发现Date在FromDate和ToDate之间,所以你看之前(索引n / 4,如果n是你的行数),那么你看之前是从日期开始,您可以在n / 4和n / 2之间查看等。您可以快速找到第一行匹配,并为ToDate执行相同操作,并选择其间的所有行。好的,那很快。请注意,服务器可能不会完全这样做,但它是为了让您深入了解索引提供的性能增益。
然后,有人告诉你(DATEDIFF(FromDate, foo_date) > 0) AND (DATEDIFF(foo_date, ToDate) >0)
。好的,所以你可以认为(DATEDIFF(FromDate, foo_date) > 0)
表示FromDate > foo_date
并且和以前一样。但是最有可能发生的是,sqlserver不会理解这一点,并且......如果这是真的,将需要检查所有行。所以你需要更多的计算时间。
我希望通过这个小例子,您可以看到使用索引可以极大地影响性能,以及为什么DATEDIFF不可思议。
我鼓励所有数据库专家(我不是)纠正我最有可能说的错误。