5

I have a query on which I used query optimiser:

  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

What surprised me was that the optimiser returned the following as over 40% faster:

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

Here are the execution plans for both:

Execution plans

How is that possible? I always thought the optimiser treats JOIN exactly as the WHERE clause in the optimised query...

4

1 回答 1

5

这里

一般来说,当您启用 CPU Costing(也称为“系统统计信息”)时,您应该会发现表扫描的成本会增加。这意味着您改进的运行时间很可能是由于执行路径的更改开始有利于执行计划。我的博客上有几篇关于系统统计的文章可能会给你更多的背景知识,还有一些从那里到其他相关文章的链接:http: //jonathanlewis.wordpress.com/category/oracle/statistics/system-stats/

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

于 2013-07-23T10:58:49.213 回答