Oracle10g Cost Base Optimizerにまつわる検証 その5

<Oracle10g Conitoringost Base Optimizerにまつわる検証 その5>
~動的サンプリングの変~
ペンネーム:りん

グリーンペペ師匠の指令を受けてCBOにまつわる検証を行って参ります。

■おさらい
先週までのおさらいです。
Oracle 10gからstatistics_level=typicalがdefaultとなり自動的にMONITORING
属性となりました。Oracle Schedulerが1日に1回統計情報を取ることにより監
視情報が消え、統計情報が作成されます。

というような感じでした。

では、当日作成されたテーブルで、まだ統計情報が作成されていない場合はど
うなるのでしょうか?

というわけで、検証したいと思います。

■環境
Redhat Linux Advanced Server 2.1
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0

■実験
テーブルを作成し、データを入れてからselect文のトレースを取得してみます。

SQL> create table emp_test as select * from emp;

表が作成されました。

SQL> alter session set sql_trace = true;

セッションが変更されました。

SQL> select * from emp_test;

統計情報が存在せずに、SELECT文が発行されているはずです。
では、このトレースファイルを見てみたいと思います。

SELECT /* OPT_DYN_SAMP */ 
    /*+ ALL_ROWS IGNORE_WHERE_CLAUSE NO_PARALLEL(SAMPLESUB) NO_PARALLEL_INDEX(SAMPLESUB) */ 
    NVL(SUM(C1),0), 
    NVL(SUM(C2),0) 
FROM (
    SELECT /*+ NO_PARALLEL("EMP_TEST") FULL("EMP_TEST") NO_PARALLEL_INDEX("EMP_TEST") */
        1 AS C1, 
        1 AS C2 
    FROM "EMP_TEST" "EMP_TEST") SAMPLESUB

おや…
動的サンプリングが再帰SQLとして実行されています。
動的サンプリングは、Oracle9i Release 2から実装された機能で統計情報がな
ければ、自動的に統計情報を取得する機能です。

SQL> show parameter optimizer_dynamic_sampling

NAME                                 TYPE        VALUE
------------------------------------ ----------- ---------------------
optimizer_dynamic_sampling           integer     2

Oracle 9i Release 2でのデフォルト値では、optimizer_dynamic_samplingの
デフォルト値は1でしたがどのように異なるのでしょうか

optimizer_dynamic_sampling = 1
-----------------------------------
次の条件を満たす場合、すべての分析されていない表をサンプリングします。
(1)分析されていない表が問合せに少なくとも1 つある場合。
(2)この分析されていない表が、別の表と結合、または副問合せかマージ不
     可能ビューにある場合。
(3)この分析されていない表に索引がない場合。
(4)この分析されていない表に、この表の動的サンプリングに使用されるブ
     ロックの数よりも多いブロックがある場合。
サンプリングされたブロック数は、動的サンプリングのブロックのデフォルト
数です(32)。
optimizer_dynamic_sampling = 2
-----------------------------------
動的サンプリングをすべての分析されていない表に適用します。 サンプリング
されたブロック数は、動的サンプリングのブロックのデフォルト数の2 倍です。

Oracle Database パフォーマンス・チューニングガイドから抜粋

と記載されています。

つまり、Oracle 10g からデフォルトで運用されていれば統計情報がないテー
ブルは、自動的に統計情報が作成されることになります。

また、明示的に動的サンプリングを行うにはdynamic_samplingヒントを使用し
ます。

select /*+ dynamic_sampling(emp_test,2) */ * from emp_test;

ただ、動的サンプリングでは、ディクショナリには格納されず共有プールに格
納され、その統計情報が使用されます。
ということは、統計情報がAged Outされる度に動的サンプリングを行うことに
なりその文、Parsingの負荷が高くなってしまいますので、注意が必要です。

…ん?
ヒント句をつけると動的サンプリングを行う→Parsingが発生する→再利用さ
れない?ま…まさか…一応チェックしてみましょう

select /*+ dynamic_sampling(emp_test,2) */ * from emp_test;

トレースファイルを見ても、再帰SQLが発生していませんでした。
再利用可能なSQL文がある場合には、やはりParsingは行われないようです。
ただし、動的サンプリングのレベルを変更した場合は、Parsingが発生します。

■まとめ
というわけで、統計情報を取得していなくとも動的サンプリングが自動的に行
われるのでCBOが利用されるということのようですね。
また、1日たてば統計情報が取得されるわけなので常時、統計情報が利用でき
るはずです。

今週はここまで

Oracle World 2004が楽しみ!茅ヶ崎にて