2013-07-23 5 views
5

私は、クエリオプティマイザ使用されているクエリがあります:私を驚か何なぜOracleオプティマイザはJOINとWHEREによって異なる方法で結合を処理しますか?

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 

は、オプティマイザは、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 

は両方のための実行計画されています:

Execution plans

はどうということは可能ですか?私はいつもhereから

+5

2番目のステートメントには、最初にはないオプティマイザヒント「NO_CPU_COSTING」があります。 2つが異なって最適化されていることは驚くべきことではありません。 –

+0

それを私にもっと詳しく説明できますか? no_cpu_costingは何をしますか? – kyooryu

+1

。 。あなたは、OracleのドキュメントでそれをGoogleに検索して調べることができます。重要な点は、オプティマイザのヒントが質問の根源となるクエリの最適化に影響することです。あなたは両方の計画を同じヒントを使って見る必要があります。 –

答えて

5

...オプティマイザの扱いが最適化されたクエリにWHERE句として正確に登録しようと思った:

一般に

あなたが有効にすると、テーブルスキャンのコストが を増加させることを見つける必要がありますCPU原価計算(「システム統計」とも呼ばれます)。これは、 は、実行計画を優先して実行した 実行パスの変更によって、実行時間が改善される可能性があることを意味します。 あなた より多くの背景を与えるかもしれない私のブログのシステム統計に関するいくつかの記事、及びそこから他の関連する 記事へのリンクのカップルがあります。つまり http://jonathanlewis.wordpress.com/category/oracle/statistics/system-stats/

は、あなたの統計情報は古いかもしれませんしかし、このクエリでは "オフにした"ので、非効率なパスを使用しないようにします。したがって、(一時的な)改善です。

関連する問題