Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does oracle optimiser treat join by JOIN and WHERE differently?

Tags:

sql

oracle

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...

like image 996
kyooryu Avatar asked Jul 23 '13 10:07

kyooryu


People also ask

How does the Oracle Optimizer work?

The optimizer compares the plans and chooses the plan with the lowest cost. The output from the optimizer is an execution plan that describes the optimum method of execution. The plans shows the combination of the steps Oracle Database uses to execute a SQL statement.

Which join is faster in Oracle?

- hash join with parallel hints: Fastest when joining a large table to a small table, hash joins perform full-table-scans, which can be parallelized for faster performance. See here, how to invoke a hash join.

What is the default Optimisation chosen by Oracle?

By default, the goal of the query optimizer is the best throughput. This means that it chooses the least amount of resources necessary to process all rows accessed by the statement. Oracle can also optimize a statement with the goal of best response time.

Does join order affect query performance in Oracle?

No. That's basic optimisation for the database; the optimizer will decide what is the best strategy to join the tables, regardless of the order in which they appear in the from clause. Save this answer.


1 Answers

From here:

In general you should find that the cost of a table scan will increase when you enable CPU Costing (also known as "System Statistics"). This means that your improved run time is likely to be due to changes in execution path that have started to favour execution plans. There are a few articles about system statistics on my blog that might give you more background, and a couple of links from there to other relevant articles: http://jonathanlewis.wordpress.com/category/oracle/statistics/system-stats/

In other words, your statistics might be stale, but since you have "turned them off" for this query, you avoid using an inefficient path: hence the (temporary?) improvement.

like image 51
davek Avatar answered Oct 13 '22 07:10

davek