我有一个包含数百万个条目的SQL表,我试图查询超过60天的条目数(Oracle 11.2.0.1.0)。
在本次实验中,我使用了3种不同版本的select语句:
(成本值由TOAD for Oracle V. 9.7.2.5提供)
select count(*) from fman_file
where dateadded >= (select sysdate - 60 from dual)
费用:65
select count(*) from fman_file
where dateadded >= sysdate - 60
费用:1909
select count(*) from fman_file
where dateadded >= sysdate - numtodsinterval(60,'day')
费用:1884
select count(*) from fman_file where dateadded >= '10.10.2009'
费用:1823年
(2009年10月10日只是一个例子日期!!!)
我没有考虑到所有查询的准确时间值,但第一个确实是最快的。
所以我尝试了一些更多的select-queries和其他子选择(比如(从双重中选择1000))并且它们(有时是WAY)比具有常量值的其他子选择更快。甚至看起来这个“WHATEVER”(Bug / Feature)也在MySQL中发生。
所以有人可以告诉我为什么第一个查询(方式)比其他查询更快?
格尔茨
P.S。:这不是关于sydate!问题是为什么变化与(选择)比其他人更快? (稍微关注Select-Variation(1。)与Constant-Variation(4。))
答案 0 :(得分:3)
在Jonathan Lewis的第6章“令人惊讶的sysdate”中,我的“基于成本的Oracle基础知识”副本中找到了一些提示。这似乎适用于9i,可能也适用于更高版本。
优化器在解析时将sysdate(和trunc(sysdate)以及sysdate的一些其他函数)视为已知常量,但sysdate + N变为未知,并获得与绑定变量相同的处理 - 这意味着修复选择性为5%。 (特别注意,sysdate + 0将从sysdate中提供不同的基数。)
显然,优化器还将select sysdate from dual
识别为已知常量。
答案 1 :(得分:1)
双重的优点是优化器理解双重是一个特殊的一行,一个 列表 - 当您在查询中使用它时,它在开发时使用这些知识 计划。
答案 2 :(得分:0)
在> =之后你是否重新尝试使用()围绕计算的数字2-4 - 在我看来,第一个语句是唯一一个计算该值一次的语句 - 对于所有其他语句,它重新计算在每一行。 例如:
select count(*) from fman_file where dateadded >= (SELECT sysdate - 60)
select count(*) from fman_file where dateadded >= (SELECT (sysdate - numtodsinterval(60,'day'))
select count(*) from fman_file where dateadded >= (SELECT CONVERT(datetime,'10.10.2009'))
注意 - 不知道在Oracle中转换为日期时间的语法 - 但是你明白了。
答案 3 :(得分:0)
您可以尝试使用Explain Plan
。这将显示查询正在执行的操作以及它们之间的差异。
设置和使用解释计划的几个链接:
http://download.oracle.com/docs/cd/B10500_01/server.920/a96533/ex_plan.htm
答案 4 :(得分:0)
而不是使用(选择sysdate - 60 from dual)我宁愿建议您使用绑定变量,该值在查询执行之前计算