2013-07-23 9 views
5

Ich habe eine Abfrage, auf das ich Abfrage-Optimierer verwendet:Warum behandelt Orakel-Optimierer Join durch JOIN und WHERE anders?

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 

Was ich war überrascht, dass die optimiser folgend als mehr als 40% schneller zurückgegeben:

für beide
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 

Hier sind die Ausführungspläne :

Execution plans

Wie ist das möglich? Ich dachte immer, die optimiser Leckereien in der optimierten Abfrage genau wie der WHERE-Klausel JOIN ...

+5

Ihre zweite Anweisung hat einen Optimiererhinweis 'NO_CPU_COSTING', den der erste nicht hat. Es ist nicht überraschend, dass die beiden unterschiedlich optimiert sind. –

+0

Können Sie mir das näher erklären? Was macht no_cpu_costing? – kyooryu

+1

. . Sie können das Google und in der Oracle-Dokumentation nachschlagen. Der wichtige Punkt ist, dass Optimizer-Hinweise die Optimierung der Abfrage beeinflussen, die die Wurzel Ihrer Frage ist. Sie müssen die Pläne beider mit den gleichen Hinweisen betrachten. –

Antwort

5

Von here:

Im Allgemeinen sollten Sie feststellen, dass die Kosten eines Table-Scan wird erhöhen, wenn Sie ermöglichen CPU Costing (auch bekannt als "System Statistics"). Diese bedeutet, dass Ihre verbesserte Laufzeit wahrscheinlich auf Änderungen im Ausführungspfad zurückzuführen ist, die begonnen haben, Ausführungspläne zu bevorzugen. Es gibt ein paar Artikel über Systemstatistiken auf meinem Blog, die Sie mehr Hintergrund und ein paar Links von dort zu anderen relevanten Artikel geben könnte: http://jonathanlewis.wordpress.com/category/oracle/statistics/system-stats/

Mit anderen Worten, könnte Ihre Statistiken abgestanden sein , aber da Sie für diese Abfrage "ausgeschaltet" haben, vermeiden Sie einen ineffizienten Pfad: daher die (temporäre?) Verbesserung.