5

クエリ オプティマイザーを使用したクエリがあります。

  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

両方の実行計画は次のとおりです。

実行計画

そんなことがあるものか?オプティマイザーは最適化されたクエリの WHERE 句とまったく同じように JOIN を扱うといつも思っていました...

4

1 に答える 1

5

ここから:

一般に、CPU コスト計算 (「システム統計」とも呼ばれます) を有効にすると、テーブル スキャンのコストが増加することがわかります。これは、実行時間が改善されたのは、実行計画を支持するようになった実行パスの変更による可能性が高いことを意味します。私のブログには、システム統計に関するいくつかの記事があり、背景を詳しく説明している可能性があります。また、そこから他の関連記事へのリンクがいくつかあります

言い換えれば、あなたの統計は古くなっているかもしれませんが、このクエリでは統計を「オフ」にしたため、非効率的なパスを使用することは避けられます。つまり、(一時的な?) 改善です。

于 2013-07-23T10:58:49.213 に答える