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:
How is that possible? I always thought the optimiser treats JOIN exactly as the WHERE clause in the optimised query...
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.
- 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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With