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

kyo*_*ryu 5 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
Run Code Online (Sandbox Code Playgroud)

让我感到惊讶的是,优化器以超过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
Run Code Online (Sandbox Code Playgroud)

以下是两者的执行计划:

执行计划

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

dav*_*vek 5

这里:

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

换句话说,您的统计信息可能是陈旧的,但由于您已为此查询"关闭",因此您可以避免使用低效路径:因此(临时?)改进.