为什么oracle optimiser以不同的方式处理JOIN和WHERE的连接?

时间:2013-07-23 10:40:28

标签: sql oracle

我有一个查询,我使用了查询优化器:

  SELECT res.studentid, 
       res.examid, 
       r.percentcorrect, 
       MAX(attempt) AS attempt 
  FROM tbl res 
  JOIN (SELECT studentid, 
             examid, 
             MAX(percentcorrect) AS percentcorrect 
        FROM tbl
        GROUP BY studentid, examid) r 
  ON r.studentid = res.studentid 
     AND r.examid = res.examid 
     AND r.percentcorrect = res.percentcorrect 
 GROUP BY res.studentid, res.examid, r.percentcorrect 
 ORDER BY res.examid

让我感到惊讶的是,优化器以超过40%的速度返回以下内容:

SELECT /*+ NO_CPU_COSTING */ res.studentid, 
       res.examid, 
       r.percentcorrect, 
       MAX(attempt) AS attempt 
  FROM tbl res, 
       (SELECT studentid, 
               examid, 
               MAX(percentcorrect) AS percentcorrect 
         FROM tbl 
         GROUP BY studentid, examid) r 
 WHERE r.studentid = res.studentid 
   AND r.examid = res.examid 
   AND r.percentcorrect = res.percentcorrect 
 GROUP BY res.studentid, res.examid, r.percentcorrect 
 ORDER BY res.examid

以下是两者的执行计划:

Execution plans

怎么可能?我一直认为优化器将JOIN完全视为优化查询中的WHERE子句......

1 个答案:

答案 0 :(得分:5)

来自here

  

通常,您会发现表扫描的成本会增加   启用CPU成本核算(也称为“系统统计”)时。这个   意味着您改进的运行时间可能是由于更改造成的   已经开始支持执行计划的执行路径。有   一些关于我博客上可能给你的系统统计数据的文章   更多背景,以及从那里到其他相关的几个链接   文章:   http://jonathanlewis.wordpress.com/category/oracle/statistics/system-stats/

换句话说,您的统计信息可能已过时,但由于您已为此查询“关闭”,因此您可以避免使用效率低下的路径:因此(临时?)改进。