为什么子选择的查询成本低于Oracle中的常量查询

时间:2010-07-07 14:25:25

标签: sql oracle oracle11g toad

我有一个包含数百万个条目的SQL表,我试图查询超过60天的条目数(Oracle 11.2.0.1.0)。

在本次实验中,我使用了3种不同版本的select语句:
(成本值由TOAD for Oracle V. 9.7.2.5提供)

  1. select count(*) from fman_file
    where dateadded >= (select sysdate - 60 from dual)

    费用:65

  2. select count(*) from fman_file
    where dateadded >= sysdate - 60

    费用:1909

  3. select count(*) from fman_file
    where dateadded >= sysdate - numtodsinterval(60,'day')

    费用:1884

  4. select count(*) from fman_file where dateadded >= '10.10.2009'
    费用:1823年 (2009年10月10日只是一个例子日期!!!)

  5. 我没有考虑到所有查询的准确时间值,但第一个确实是最快的。

    所以我尝试了一些更多的select-queries和其他子选择(比如(从双重中选择1000))并且它们(有时是WAY)比具有常量值的其他子选择更快。甚至看起来这个“WHATEVER”(Bug / Feature)也在MySQL中发生。

    所以有人可以告诉我为什么第一个查询(方式)比其他查询更快?

    格尔茨

    P.S。:这不是关于sydate!问题是为什么变化与(选择)比其他人更快? (稍微关注Select-Variation(1。)与Constant-Variation(4。))

5 个答案:

答案 0 :(得分:3)

在Jonathan Lewis的第6章“令人惊讶的sysdate”中,我的“基于成本的Oracle基础知识”副本中找到了一些提示。这似乎适用于9i,可能也适用于更高版本。

  

优化器在解析时将sysdate(和trunc(sysdate)以及sysdate的一些其他函数)视为已知常量,但sysdate + N变为未知,并获得与绑定变量相同的处理 - 这意味着修复选择性为5%。 (特别注意,sysdate + 0将从sysdate中提供不同的基数。)

显然,优化器还将select sysdate from dual识别为已知常量。

答案 1 :(得分:1)

Tom Kyte

  

双重的优点是优化器理解双重是一个特殊的一行,一个   列表 - 当您在查询中使用它时,它在开发时使用这些知识   计划。

答案 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

http://www.adp-gmbh.ch/ora/explainplan.html

答案 4 :(得分:0)

而不是使用(选择sysdate - 60 from dual)我宁愿建议您使用绑定变量,该值在查询执行之前计算