ヘッダーをスキップ
Oracle Databaseパフォーマンス・チューニング・ガイド
11gリリース1(11.1)
E05743-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

13 オプティマイザ統計の管理

この章では、問合せオプティマイザにとって統計が重要である理由、およびDBMS_STATSパッケージを使用したオプティマイザ統計の収集方法と使用方法を説明します。

この章には次の項があります。

13.1 統計について

オプティマイザ統計は、データベースとそのオブジェクトに関する詳細情報を記述するデータの集合です。これらの統計は、問合せオプティマイザで各SQL文に最適の実行計画を選択するために使用されます。オプティマイザ統計には次のものがあります。

オプティマイザ統計はデータ・ディクショナリに格納されます。また、データ・ディクショナリ・ビューを使用して表示できます。「統計の表示」を参照してください。

データベース内のオブジェクトは常に変化するため、これらのデータベース・オブジェクトが正確に記述されるように統計を定期的に更新する必要があります。統計はOracleにより自動的にメンテナンスされます。また、DBMS_STATSパッケージを使用するとオプティマイザ統計を手動でメンテナンスできます。自動プロセスと手動プロセスについては、「自動オプティマイザ統計収集」または「手動統計収集」を参照してください。

DBMS_STATSパッケージにも、統計を管理するためのプロシージャが用意されています。統計のコピーを保存してリストアできます。あるシステムから統計をエクスポートし、別のシステムにインポートできます。たとえば、本番システムからテスト・システムに統計をエクスポートできます。また、統計が変更されないようにロックすることも可能です。ロック方法の詳細は、「表統計またはスキーマ統計のロック」を参照してください。

13.2 自動オプティマイザ統計収集

推奨されるオプティマイザ統計収集方法は、Oracle Databaseで統計の自動収集を可能にすることです。Oracle Databaseでは、すべてのデータベース・オブジェクトのオプティマイザ統計が自動的に収集され、自動化されたメンテナンス・タスクで統計がメンテナンスされます。自動化メンテナンス・タスク・インフラストラクチャ(自動タスク)により、各タスクがスケジュールされ、メンテナンス・ウィンドウと呼ばれるOracleスケジューラ・ウィンドウで自動的に実行されます。デフォルトでは、曜日ごとに1つのウィンドウがスケジュールされます。これらのメンテナンス・ウィンドウの属性(開始時刻と終了時刻、頻度、曜日など)は、カスタマイズできます。自動タスクでは、統計収集が自動化メンテナンス・タスクとしてメンテナンス・ウィンドウでスケジュールされ、統計が欠落または失効しているデータベースのすべてのスキーマ・オブジェクトに関するオプティマイザ統計が自動的に収集されます。このプロセスは、自動オプティマイザ統計収集と呼ばれます。

自動オプティマイザ統計収集では、DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROCプロシージャをコールしてオプティマイザ統計を収集します。GATHER_DATABASE_STATS_JOB_PROCプロシージャによりデータベース・オブジェクトの統計が収集されるのは、オブジェクトの統計が以前に収集されていない場合、または基礎となるオブジェクトが大幅に(行の10%以上が)変更されたために既存の統計が失効している場合です。DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROCは内部プロシージャですが、その動作はGATHER AUTOオプションを使用するDBMS_STATS.GATHER_DATABASE_STATSプロシージャとほとんど同じです。主な違いは、DBMS_STATS.GATHER_DATABASE_STATS_JOB_PROCプロシージャでは、統計を必要とするデータベース・オブジェクトに優先順位が設定されるため、更新済の統計を最も必要とするオブジェクトが最初に処理されることです。これにより、メンテナンス・ウィンドウがクローズする前に、最も必要性の高い統計が確実に収集されます。

自動オプティマイザ統計収集により、問合せオプティマイザの管理に関連する多数の手動タスクが不要になり、統計の欠落または失効が原因で不適切な実行計画が生成されるリスクが大幅に低下します。

この項では、次の項目について説明します。

13.2.1 自動オプティマイザ統計収集の有効化

オプティマイザ統計は、統計が失効または欠落しているデータベースのすべてのオブジェクトに関する統計を収集する自動オプティマイザ統計収集によって自動的に収集されます。自動オプティマイザ統計収集は、自動化メンテナンス・タスク・インフラストラクチャ(自動タスク)の一部として実行されます。この機能は、事前定義されたすべてのメンテナンス・ウィンドウで実行されるようデフォルトで有効化されています。

なんらかの理由で自動オプティマイザ統計収集が無効になった場合、次のようにDBMS_AUTO_TASK_ADMINパッケージのENABLEプロシージャを使用してこの機能を有効化できます。

BEGIN
  DBMS_AUTO_TASK_ADMIN.ENABLE(
    client_name => 'auto optimizer stats collection',
    operation => NULL,
    window_name => NULL);
END;
/

自動オプティマイザ統計収集を無効化する場合、次のようにDBMS_AUTO_TASK_ADMINパッケージのDISABLEプロシージャを使用してこの機能を無効化できます。

BEGIN
  DBMS_AUTO_TASK_ADMIN.DISABLE(
    client_name => 'auto optimizer stats collection',
    operation => NULL,
    window_name => NULL);
END;
/

自動オプティマイザ統計収集は、「失効している統計の判別」で説明するように変更監視機能に依存します。この機能が無効になっている場合、自動オプティマイザ統計収集ジョブでは失効している統計を検出できません。この機能は、STATISTICS_LEVELパラメータがTYPICALまたはALLに設定されている場合に有効になります。デフォルト値はTYPICALです。


関連項目:

  • 自動タスク・インフラストラクチャの詳細は、『Oracle Database管理者ガイド』を参照してください。

  • DBMS_AUTO_TASK_ADMINパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。


13.2.2 統計収集時の考慮事項

この項では、次の内容を説明します。

13.2.2.1 手動統計を使用する場合

普通の速度で変更されるほとんどのデータベース・オブジェクトの場合は、自動オプティマイザ統計収集で十分です。ただし、自動オプティマイザ統計収集では不十分な場合があります。自動オプティマイザ統計収集はメンテナンス・ウィンドウ中に実行されるため、1日を通して大幅に変更された表の統計は失効する可能性があります。通常、この種のオブジェクトには次の2つのタイプがあります。

  • 日中に削除または切り捨てられて再作成された揮発性の表

  • オブジェクトの合計サイズの10%以上を追加する大規模バルク・ロードのターゲットであるオブジェクト

揮発性の高い表の場合は、次の2つのアプローチがあります。

  • これらの表の統計をNULLに設定できます。Oracleでは、統計のない表が検出されると、問合せ最適化の一部として必要な統計が動的に収集されます。この動的サンプリング機能はOPTIMIZER_DYNAMIC_SAMPLINGパラメータにより制御されます。このパラメータは2以上の値に設定する必要があります。デフォルト値は2です。統計は、削除してからロックすることでNULLに設定できます。

    BEGIN
      DBMS_STATS.DELETE_TABLE_STATS('OE','ORDERS');
      DBMS_STATS.LOCK_TABLE_STATS('OE','ORDERS');
    END;
    /
    

    設定できるサンプリング・レベルの詳細は、「動的サンプリング・レベル」を参照してください。

  • この種の表の統計は、表の典型的な状態を表す値に設定できます。表に代表的な行数が含まれているときに、その表の統計を収集し、統計をロックする必要があります。

    通常、この方法は自動オプティマイザ統計収集よりも効率的です。これは、夜間のバッチ・ウィンドウで表に関して生成された統計が、日中のワークロードに関して最も適切な統計であるとはかぎらないためです。

バルク・ロード対象の表の場合は、統計収集プロシージャをロード・プロセスの直後に、可能であればバルク・ロードを実行するのと同じスクリプトまたはジョブの一部として、実行する必要があります。

外部表の場合、GATHER_SCHEMA_STATSGATHER_DATABASE_STATSおよび自動オプティマイザ統計収集処理中には統計は収集されません。ただし、GATHER_TABLE_STATSを使用すると外部表の統計を個別に収集できます。外部表のサンプリングはサポートされていないため、ESTIMATE_PERCENTオプションは明示的にNULLに設定する必要があります。外部表のデータ操作は許可されないため、対応するファイルに変更があったときに外部表を分析すれば十分です。

STATISTICS_LEVELBASICに設定して監視機能を無効にすると、自動オプティマイザ統計収集では失効している統計を検出できません。この場合は、統計を手動で収集する必要があります。自動監視機能の詳細は、「失効している統計の判別」を参照してください。

システム統計も、手動で収集する必要があります。この種の統計は自動的には収集されません。詳細は、「システム統計」を参照してください。

動的パフォーマンス表など、固定オブジェクトの統計は、GATHER_FIXED_OBJECTS_STATSプロシージャを使用して手動で収集する必要があります。固定オブジェクトには現行のデータベース・アクティビティが記録されます。データベースに典型的なアクティビティがあるときに統計を収集する必要があります。

13.2.2.2 前のバージョンの統計のリストア

ディクショナリ内で統計が変更されるたびに、後でリストアできるように前のバージョンの統計が自動的に保存されます。統計をリストアするには、DBMS_STATSパッケージのRESTOREプロシージャを使用します。詳細は、「前のバージョンの統計のリストア」を参照してください。

13.2.2.3 統計のロック

「手動統計を使用する場合」で説明したように、揮発性の高い表など、表またはスキーマに関してDBMS_STATS_JOBプロセスによる新規統計の収集を中止する必要がある場合があります。このような場合は、DBMS_STATSパッケージに表またはスキーマの統計をロックするためのプロシージャが用意されています。詳細は、「表統計またはスキーマ統計のロック」を参照してください。

13.3 手動統計収集

自動オプティマイザ統計収集を使用しないように選択した場合は、システム・スキーマを含め、すべてのスキーマ内で統計を手動で収集する必要があります。データベース内のデータが定期的に変化する場合は、統計がデータベース・オブジェクトの特性を正確に表すように、統計も定期的に収集する必要があります。

13.3.1 DBMS_STATSプロシージャによる統計の収集

統計はDBMS_STATSパッケージを使用して収集されます。このPL/SQLパッケージは、統計の変更、表示、エクスポート、インポートおよび削除にも使用されます。


注意:

オプティマイザ統計の収集に、ANALYZE文でCOMPUTE句およびESTIMATE句を使用しないでください。これらの句は下位互換性のためにのみサポートされており、将来のリリースでは削除される可能性があります。DBMS_STATSパッケージを使用するほうが、より広範囲で正確な統計セットが効率的に収集されます。

オプティマイザ統計の収集に関係しない次のような用途には、引き続きANALYZE文を使用できます。

  • VALIDATEまたはLIST CHAINED ROWS句を使用する場合

  • 空きリスト・ブロックの情報を収集する場合


DBMS_STATSパッケージでは、表と索引の統計、および表の列とパーティションの個別の統計を収集できます。クラスタ統計は収集できません。ただし、DBMS_STATSを使用して、全クラスタのかわりに個別の表の統計を収集できます。

表、列または索引の統計を生成するとき、分析したオブジェクトの統計がすでにデータ・ディクショナリ内に収録されている場合、Oracleは既存の統計を更新します。古い統計は保存され、後で必要に応じてリストアできます。「前のバージョンの統計のリストア」を参照してください。

システム・スキーマの統計を収集する場合は、DBMS_STATS.GATHER_DICTIONARY_STATSプロシージャを使用できます。このプロシージャでは、SYSSYSTEMを含むすべてのシステム・スキーマと、CTXSYSDRSYSなどの他のオプション・スキーマの統計が収集されます。

データベース・オブジェクトの統計が更新されると、そのオブジェクトにアクセスする現在解析済のSQL文が無効にされます。文が次に実行されるときに、文が再解析され、オプティマイザは新しい統計に基づいて新しい実行計画を自動的に選択します。リモート・データベース上で新しい統計を持つオブジェクトにアクセスする分散型の文は、無効にされません。新しい統計は、次回にSQL文が解析されると有効になります。

表13-1に、DBMS_STATSパッケージにおけるデータベース・オブジェクトの統計収集のためのプロシージャを示します。

表13-1 DBMS_STATSパッケージの統計収集プロシージャ

プロシージャ 収集対象

GATHER_INDEX_STATS

索引統計

GATHER_TABLE_STATS

表、列および索引の統計

GATHER_SCHEMA_STATS

スキーマ内のすべてのオブジェクトの統計

GATHER_DICTIONARY_STATS

すべてのディクショナリ・オブジェクトの統計

GATHER_DATABASE_STATS

データベース内のすべてのオブジェクトの統計



関連項目:

すべてのDBMS_STATSプロシージャの構文と例については、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

前述のプロシージャを統計収集に使用する場合は、次のようにいくつか重要な考慮事項があります。

13.3.1.1 サンプリングを使用した統計収集

統計収集操作では、サンプリングを使用して統計を予測できます。サンプリングは、統計収集の重要なテクニックです。サンプリングを使用せずに統計を収集するには、全表スキャンと表全体のソートが必要です。サンプリングを使用すると、統計収集に必要なリソースが最小限に抑えられます。

サンプリングは、DBMS_STATSプロシージャのESTIMATE_PERCENT引数を使用して指定します。サンプリング率は任意の値に設定できますが、必要な統計を正確に収集しながらパフォーマンスを最大限まで高めるために、DBMS_STATS収集プロシージャのESTIMATE_PERCENTパラメータをDBMS_STATS.AUTO_SAMPLE_SIZEに設定することをお薦めします。AUTO_SAMPLE_SIZEを使用すると、Oracleではオブジェクトの統計プロパティに基づいて適切な統計に必要な最適のサンプル・サイズが決定されます。統計のタイプごとに要件が異なるため、実際に取得されるサンプルのサイズは、表、列または索引間で異なる場合があります。たとえば、自動サンプリングでOEスキーマ内のすべての表に関する表統計および列統計情報を収集するには、次のように使用できます。

EXECUTE DBMS_STATS.GATHER_SCHEMA_STATS('OE',DBMS_STATS.AUTO_SAMPLE_SIZE);

ESTIMATE_PERCENTパラメータを手動で指定すると、指定されたパーセントで生成されたサンプルの大きさが十分でない場合に、DBMS_STATS収集プロシージャによりサンプリング率が自動的に増加されます。これによって、見積り値の変動が少なくなり、安定性が保証されます。

13.3.1.2 パラレル統計収集

統計の収集操作は、シリアルまたはパラレルのどちらでも実行できます。並列度は、DBMS_STATS収集プロシージャのDEGREE引数で指定できます。パラレル統計収集はサンプリングと併用できます。DEGREEパラメータをDBMS_STATS.AUTO_DEGREEに設定することをお薦めします。このように設定すると、Oracleはオブジェクトのサイズとパラレル関連のinit.oraパラメータの設定に基づいて適切な並列度を選択できます。

クラスタ索引、ドメイン索引およびビットマップ結合索引など、特定のタイプの索引統計は、パラレルでは収集されないことに注意してください。

13.3.1.3 パーティション・オブジェクトの統計

パーティション表および索引に対して、DBMS_STATSは、各パーティションの個別の統計を収集できます。また、全表または全索引のグローバル統計も収集できます。コンポジット・パーティションについても同様に、DBMS_STATSはサブパーティション、パーティション、全表および全索引の個別の統計を収集できます。収集するパーティション統計のタイプは、DBMS_STATS収集プロシージャのGRANULARITY引数で指定します。

最適化されたSQL文によっては、オプティマイザがパーティション(サブパーティション)統計またはグローバル統計の使用を選択する場合があります。どちらのタイプの統計もほとんどのアプリケーションにとって重要であり、GRANULARITYパラメータをAUTOに設定して両方のタイプのパーティション統計を収集することをお薦めします。

パーティション表では、通常、新規データは新規パーティションにロードされます。新規パーティションの追加とデータのロードに合せ、統計は新規パーティションで収集する必要があり、グローバル統計は最新の状態に維持する必要があります。パーティション表のINCREMENTAL値がTRUEに設定され、GRANULARITYパラメータがAUTOに設定された状態でその表の統計を収集すると、Oracleでは、(表全体ではなく)変更済のパーティションのみがスキャンされ、新規パーティションの統計収集とグローバル表統計の更新が行われます。パーティション表のINCREMENTAL値がFALSE(デフォルト値)に設定されている場合、グローバル統計の維持には全表スキャンが使用されます。大規模な表では、これは大量にリソースを消費し、時間のかかる操作です。


注意:

パーティション表でINCREMENTALTRUEに設定すると、SYSAUX表領域ではグローバル統計を維持するために追加の領域が使用されます。

パーティション表のINCREMENTAL値を変更するには、DBMS_STATS.SET_TABLE_PREFプロシージャを使用します。詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。


13.3.1.4 列統計情報とヒストグラム

表の統計を収集する場合、DBMS_STATSでは表内の列のデータ配分情報が収集されます。データ配分に関して最も基本的な情報は、列の最大値と最小値です。ただし、列のデータに偏りがある場合、このレベルの統計ではオプティマイザのニーズが十分に満たされない場合があります。データ配分に偏りがある場合は、指定した列のデータ配分を記述するヒストグラムも列統計の一部として作成できます。ヒストグラムの詳細は、「ヒストグラムの表示」を参照してください。

ヒストグラムは、DBMS_STATS収集プロシージャのMETHOD_OPT引数を使用して指定します。METHOD_OPTFOR ALL COLUMNS SIZE AUTOに設定することをお薦めします。この設定では、どの列にヒストグラムが必要であるかということと各ヒストグラムのバケット数(サイズ)が、Oracleにより自動的に判別されます。また、これらの情報は手動でも指定できます。


注意:

DBMS_STATSを使用するとき表からすべての行を削除する必要がある場合、同じ表を削除して再度作成するかわりに、TRUNCATEを使用します。表が削除されると、自動ヒストグラム収集機能が使用するワークロード情報と、RESTORE_*_STATSプロシージャが使用する保存された統計履歴が消失します。このデータなしでは、これらの機能は適切に動作しません。

13.3.1.5 拡張統計

Oracleでは、表内の列のグループまたは列の式に関する統計も収集できます。これらの詳細は、次の項を参照してください。

13.3.1.6 複数列の統計

単一表の複数列が問合せのwhere句で組み合されて使用される場合(複数の単一列条件)、列と列の間の関係が、その列グループの組合せ選択に大きな影響を与える可能性があります。

例として、SHスキーマのcustomers表を検討します。cust_state_province列とcountry_id列は、各顧客のcust_state_provincecountry_idを決定するという関係にあります。次のように、cust_state_provinceCaliforniaであるという条件でcustomers表を問い合せます。

Select count(*)
from sh.customers
where cust_state_province = 'CA';

次の値が戻されます。

 COUNT(*)
----------
    3341

country_id列が52790(アメリカ合衆国)の場合、次のようにcountry_idに関する別の条件を追加しても結果は変わりません。

Select count(*)
from customers
where cust_state_province = 'CA'
and country_id=52790;

前述の問合せと同じ値が戻されます。

 COUNT(*)
----------
    3341

ここで、country_idに52775(ブラジル)などの別の値が含まれる場合に、次の問合せを実行するとします。

Select count(*)
from   customers
where  cust_state_province = 'CA'
and    country_id=52775;

戻される値は、次のようになります。

 COUNT(*)
----------
       0

個々の列統計が対象の場合、オプティマイザでは、cust_state_province列とcountry_id列の関係を認識できません。これらの列をグループ(列グループ)として統計を収集することで、オプティマイザでは、個々の列統計に基づいて値を生成することなく、そのグループに関するより正確な選択値を特定できます。

デフォルトでは、Oracleにより、ヒストグラムの場合と同様にワークロード分析に基づいて表の列グループが作成されます。

DBMS_STATSパッケージを使用して手動で列グループを作成することもできます。このパッケージを使用すると、列グループの作成、列グループ名の取得、または表からの列グループの削除が可能になります。

13.3.1.6.1 列グループの作成

create_extended_statisticsファンクションを使用して、列グループを作成します。create_extended_statisticsファンクションでは、新規に作成された列グループのシステム生成名が戻されます。表13-2に、このファンクションの入力パラメータを示します。

表13-2 create_extended_statisticsファンクションのパラメータ

パラメータ 説明

owner

スキーマ所有者。NULLは現在のスキーマを示します。

tab_name

列グループが追加される表の名前。

extension

列グループの列。


たとえば、cust_state_provinceおよびcountry_id列で構成される列グループをSHスキーマのcustomers表に追加する場合、次のようにします。

declare
  cg_name varchar2(30);
begin
 cg_name := dbms_stats.create_extended_stats(null,'customers', '(cust_state_province,country_id)');
end;
/
13.3.1.6.2 列グループの取得

show_extended_stats_nameファンクションを使用して、任意の列セットに対応する列グループの名前を取得します。表13-3に、このファンクションの入力パラメータを示します。

表13-3 show_extended_stats_nameファンクションのパラメータ

パラメータ 説明

owner

スキーマ所有者。NULLは現在のスキーマを示します。

tab_name

列グループが属している表の名前。

extension

列グループの名前。


たとえば、次の問合せを使用すると、customers表の列セットの列グループ名を取得できます。

select sys.dbms_stats.show_extended_stats_name('sh','customers',
       '(cust_state_province,country_id)') col_group_name
from dual;

出力例は次のとおりです。

COL_GROUP_NAME
----------------
SYS_STU#S#WF25Z#QAHIHE#MOFFMM
13.3.1.6.3 列グループの削除

drop_extended_statsファンクションを使用して、表から列グループを削除します。表13-4に、このファンクションの入力パラメータを示します。

表13-4 drop_extended_statsファンクションのパラメータ

パラメータ 説明

owner

スキーマ所有者。NULLは現在のスキーマを示します。

tab_name

列グループが属している表の名前。

extension

削除する列グループの名前。


たとえば、次の文を使用すると、customers表から列グループを削除できます。

exec dbms_stats.drop_extended_stats('sh','customers','(cust_state_province,country_id)');
13.3.1.6.4 列グループの監視

ディクショナリ表user_stat_extensionsを使用して、複数列の統計に関する情報を取得します。

Select extension_name, extension
from user_stat_extensions
where table_name='CUSTOMERS';
EXTENSION_NAME                                            EXTENSION
-------------------------------------------------------------------------
SYS_STU#S#WF25Z#QAHIHE#MOFFMM_     ("CUST_STATE_PROVINCE","COUNTRY_ID")

次の問合せを使用すると、個別値の数と、列グループにヒストグラムが作成されているかどうかを確認できます。

select e.extension col_group, t.num_distinct, t.histogram
  2  from user_stat_extensions e, user_tab_col_statistics t
  3  where e.extension_name=t.column_name
  4  and e.table_name=t.table_name
  5  and t.table_name='CUSTOMERS';
COL_GROUP                                                                NUM_DISTINCT                   HISTOGRAM
-------------------------------------------------------------------------------
("COUNTRY_ID","CUST_STATE_PROVINCE")               145                           FREQUENCY
13.3.1.6.5 列グループの統計の収集

DBMS_STATSパッケージのMETHOD_OPT引数を使用して、列グループの統計を収集します。この引数の値をFOR ALL COLUMNS SIZE AUTOに設定すると、オプティマイザでは、既存のすべての列グループに関する統計が収集されます。新規の列グループに関する統計を収集するには、FOR COLUMNSを使用してグループを指定します。列グループは、統計収集の一部として自動的に作成されます。

たとえば、次の文では、customers表のcust_state_provinceおよびcountry_id列に対応する新規列グループが作成され、表全体と新規列グループに関する統計(ヒストグラムを含む)が収集されます。

EXEC DBMS_STATS.GATHER_TABLE_STATS('SH','CUSTOMERS',METHOD_OPT =>
'FOR ALL COLUMNS SIZE SKEWONLY
FOR COLUMNS (CUST_STATE_PROVINCE,COUNTRY_ID) SIZE SKEWONLY');

注意:

オプティマイザでは、等価述語で複数列の統計のみが使用されます。

13.3.1.7 式の統計

問合せのwhere句で列に関数が適用される場合(function(col1)=constant)、オプティマイザでは、その関数が列の選択性に与える影響を認識できません。式function(col1)に関する式の統計を収集することで、オプティマイザではより正確な選択値を特定できます。

このような関数の例は、次のとおりです。

SELECT COUNT(*)
FROM   CUSTOMERS
WHERE  LOWER(CUST_STATE_PROVINCE)='CA';
13.3.1.7.1 式の統計の作成

gather_table_statsプロシージャの一部として、次のように式の統計を作成できます。

exec dbms_stats.gather_table_stats('sh','customers', method_opt =>
'for all columns size skewonly
 for columns (lower(cust_state_province)) size skewonly');

これを行うには、次のようにcreate_extended_statisticsファンクションも使用できます。

select
dbms_stats.create_extended_stats(null,'customers','(lower(cust_state_province))')
from dual;
13.3.1.7.2 式の統計の監視

ディクショナリ表user_stat_extensionsを使用して、式の統計に関する情報を取得します。

Select extension_name, extension
from user_stat_extensions
where table_name='CUSTOMERS';
EXTENSION_NAME                                           EXTENSION
------------------------------------------------------------------------
SYS_STUBPHJSBRKOIK9O2YV3W8HOUE         (LOWER("CUST_STATE_PROVINCE"))

次の問合せを使用すると、個別値の数と、ヒストグラムが作成されているかどうかを確認できます。

select e.extension col_group, t.num_distinct, t.histogram
  2  from user_stat_extensions e, user_tab_col_statistics t
  3  where e.extension_name=t.column_name
  4  and t.table_name='CUSTOMERS';
COL_GROUP                                                           NUM_DISTINCT                          HISTOGRAM
------------------------------------------------------------------------
(LOWER("CUST_STATE_PROVINCE"))                           145                            FREQUENCY
13.3.1.7.3 式の統計の削除

drop_extended_statsファンクションを使用して、表から式の統計を削除します。

exec dbms_stats.drop_extended_stats(null,'customers','(lower(country_id))');

13.3.1.8 失効している統計の判別

データベース・オブジェクトは時間の経過につれて変更されるため、その統計を定期的に収集する必要があります。特定のデータベース・オブジェクトに新規データベース統計が必要かどうかを判別するために、Oracleには表監視機能が用意されています。この監視機能は、STATISTICS_LEVELTYPICALまたはALLに設定されている場合にデフォルトで有効になります。監視では、最新の統計収集以降の、表に対するINSERTUPDATEおよびDELETEの概数と、その表が切り捨てられているかどうかを追跡します。表の変更情報は、USER_TAB_MODIFICATIONSビューで表示できます。データ変更後は、このビューに情報が伝播するまでに数分の遅延が発生することがあります。メモリーに保存されている未処理の監視情報を即時に反映させるには、DBMS_STATS.FLUSH_DATABASE_MONITORING_INFOプロシージャを使用します。

OPTIONSパラメータをGATHER STALEまたはGATHER AUTOに設定すると、GATHER_DATABASE_STATSまたはGATHER_SCHEMA_STATSプロシージャは、統計が失効している表に関して新規の統計を収集します。監視される表の変更が10%を超えた場合、これらの統計は失効したものとみなされ、再度収集されます。

13.3.1.9 ユーザー定義統計

ユーザー定義のオプティマイザ統計を作成して、ユーザー定義の索引およびファンクションをサポートできます。統計タイプを列またはドメイン索引に対応付ける場合、データベース・オブジェクトの統計が収集されるたびに、Oracleでは統計タイプの統計コレクション・メソッドがコールされます。

Oracleにより式が表すのと同等の列統計情報を収集できるように、ファンクション索引の作成後に表の新規列統計を収集する必要があります。そのためには、METHOD_OPT引数をFOR ALL HIDDEN COLUMNSに設定して統計収集プロシージャをコールします。


関連項目:

ユーザー定義統計の実装の詳細は、『Oracle Databaseデータ・カートリッジ開発者ガイド』を参照してください。

13.3.2 統計を収集する時期

統計を手動で収集する場合は、その収集方法を決定するのみでなく、新規統計の収集時期と頻度も決定する必要があります。

表の増分変更が行われるアプリケーションの場合は、新規の統計を週または月に1回収集するのみでよい場合があります。このような環境で最も簡単な統計収集方法は、スクリプトまたはジョブ・スケジューリング・ツールを使用して、GATHER_SCHEMA_STATSおよびGATHER_DATABASE_STATSプロシージャを定期的に実行することです。収集の頻度によって、統計収集プロセスで起こるオーバーヘッドの処理に対し、オプティマイザの正確な統計を出すタスクのバランスをとります。

バルク・ロードを使用する場合など、バッチ操作で逐次変更される表の場合は、その表の統計をバッチ操作の一部として収集する必要があります。ロード操作の完了直後にDBMS_STATSプロシージャをコールしてください。

パーティション表の場合、通常は1つのパーティションのみが変更されます。このような場合は、表全体の統計を収集するのではなく、変更があったパーティションの統計のみを収集できます。ただし、パーティション表のグローバル統計の収集も必要な場合があります。


関連項目:

DBMS_STATSパッケージのGATHER_SCHEMA_STATSおよびGATHER_DATABASE_STATSプロシージャの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

13.3.3 DBMS_STATSファンクションによる統計の比較

DBMS_STATSを使用すると、2つの異なるソースの表の統計を比較できます。表13-5に、統計を比較するためのDBMS_STATSパッケージのファンクションを示します。

表13-5 統計を比較するDBMS_STATSパッケージのファンクション

プロシージャ 比較対象

DIFF_TABLE_STATS_IN_PENDING

保留中の統計とタイムスタンプの時点の統計またはディクショナリの統計

DIFF_TABLE_STATS_IN_STATTAB

2つの異なるソースの表の統計

DIFF_TABLE_STATS_IN_HISTORY

過去の2つのタイムスタンプからの表の統計、およびそれらのタイムスタンプの時点の統計


表13-5のファンクションでは、索引、列およびパーティションなどの依存オブジェクトの統計も比較します。これらの統計間の差分が特定のしきい値を超える場合、両方のソースのオブジェクトの統計が表示されます。ファンクションの引数としてしきい値を指定できます。デフォルトは10%です。Oracle Databaseでは、最初のソースに相当する統計を基本として使用し、異なる割合を計算します。


関連項目:

DBMS_STATSパッケージのDIFF_TABLE_STATS_*ファンクションの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

13.4 システム統計

システム統計は、問合せオプティマイザに対してシステムのハードウェア特性(I/OとCPUのパフォーマンスおよび使用率など)を記述します。実行計画の選択時に、オプティマイザで各問合せに必要なI/OおよびCPUリソースが見積られます。システム統計を使用すると、問合せオプティマイザはI/OおよびCPUコストをより正確に見積ることができ、問合せオプティマイザはより適切な実行計画を選択できます。

システム統計を収集するとき、指定された期間のシステム・アクティビティ(作業負荷統計)が分析されるか、作業負荷(非作業負荷統計)がシミュレートされます。統計は、DBMS_STATS.GATHER_SYSTEM_STATSプロシージャを使用して収集されます。システム統計を収集することをお薦めします。


注意:

ディクショナリ・システム統計を更新するには、DBA権限またはGATHER_SYSTEM_STATISTICSロールが必要です。

表13-6に、DBMS_STATSパッケージにより収集されたオプティマイザのシステム統計と、特定のシステム統計の収集または手動設定のオプションを示します。

表13-6 DBMS_STATパッケージ内のオプティマイザのシステム統計

パラメータ名 説明 初期化 統計の収集または設定のオプション 単位

cpuspeedNW

作業負荷のない場合のCPU速度を表します。CPU速度は、1秒当たりのCPU平均サイクル数です。

システム起動時

gathering_mode = NOWORKLOADに設定するか、または統計を手動で設定します。

100万/秒

ioseektim

I/Oシーク時間は、シーク時間、待機時間およびオペレーティング・システム・オーバーヘッド時間を合計したものです。

システム起動時

10(デフォルト)

gathering_mode = NOWORKLOADに設定するか、または統計を手動で設定します。

ミリ秒

iotfrspeed

I/O転送速度は、1回の読取りリクエストでOracleデータベースがデータを読み取ることができる速度です。

システム起動時

4096(デフォルト)

gathering_mode = NOWORKLOADに設定するか、または統計を手動で設定します。

バイト/ミリ秒

cpuspeed

作業負荷をかけた場合のCPU速度を表します。CPU速度は、1秒当たりのCPU平均サイクル数です。

なし

gathering_mode = NOWORKLOADINTERVALまたはSTART|STOPに設定するか、または統計を手動で設定します。

100万/秒

maxthr

最大I/Oスループットは、I/Oサブシステムが発揮できる最大スループットです。

なし

gathering_mode = NOWORKLOADINTERVALまたはSTART|STOPに設定するか、または統計を手動で設定します。

バイト/秒

slavethr

スレーブI/Oスループットは、パラレル・スレーブの平均I/Oスループットです。

なし

gathering_mode = INTERVALまたはSTART|STOPに設定するか、または統計を手動で設定します。

バイト/秒

sreadtim

単一ブロック読取り時間は、単一ブロックをランダムに読み取る平均時間です。

なし

gathering_mode = INTERVALまたはSTART|STOPに設定するか、または統計を手動で設定します。

ミリ秒

mreadtim

マルチブロック読取りは、マルチブロックを順に読み取る平均時間です。

なし

gathering_mode = INTERVALまたはSTART|STOPに設定するか、または統計を手動で設定します。

ミリ秒

mbrc

マルチブロック・カウントは、平均マルチブロック順次読取りカウントです。

なし

gathering_mode = INTERVALまたはSTART|STOPに設定するか、または統計を手動で設定します。

ブロック


表、索引、列の統計とは異なり、システム統計の更新時には、すでに解析されているSQL文は無効にされません。新しいSQL文はすべて、新しい統計を使用して解析されます。

システム統計の収集方法には2つのオプションがあります。

これらのオプションは、物理データベースおよび作業負荷の収集プロセスを容易に使用できるようにします。作業負荷システム統計が収集されると、非作業負荷システム統計は無視されます。非作業負荷システム統計は、データベースの初回の起動時にデフォルト値に初期化されます。


関連項目:

システム統計を実装するためのDBMS_STATSパッケージのプロシージャの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

13.4.1 作業負荷統計

Oracle9iで導入された作業負荷統計は、シングルおよびマルチブロックの読取り時間、mbrc、CPU速度(cpuspeed)、最大システム・スループットおよび平均スレーブ・スループットを収集します。sreadtimmreadtimおよびmbrcは、作業負荷の開始から終了までの2点間の、物理的な順次およびランダム読取りの数を比較して計算されます。これらの値は、バッファ・キャッシュが同期読取りリクエストを完了したときに変更されるカウンタを通して実装されます。このカウンタはバッファ・キャッシュ内にあるため、これらにはI/O遅延のみならず、ラッチの競合およびタスク・スイッチングに関連する待機も含まれています。このように、作業負荷統計は、作業負荷ウィンドウでシステムが実行するアクティビティに応じて異なります。ラッチ競合およびI/Oスループットの両方でシステムがI/Oバウンドの場合、この状態は統計に反映され、この統計が使用された後でI/O低減化集中計画が促進されます。さらに、作業負荷統計収集は、追加のオーバーヘッドを生成しません。

リリース9.2では、全表スキャン(FTS)の下限を設定するための最大I/Oスループットおよび平均スレーブ・スループットが追加されました。

13.4.1.1 作業負荷統計の収集

作業負荷統計を収集するには、次のいずれかの手順を実行します。

  • 作業負荷ウィンドウの開始時にdbms_stats.gather_system_stats('start')プロシージャを実行し、作業負荷ウィンドウの終了時にdbms_stats.gather_system_stats('stop')プロシージャを実行します。

  • dbms_stats.gather_system_stats('interval', interval=>N)を実行します。Nは、統計収集が自動停止する時間(分)です。

システム統計を削除するには、dbms_stats.delete_system_stats()を実行します。作業負荷統計が削除され、デフォルトの非作業負荷統計にリセットされます。

13.4.1.2 マルチブロック読取りカウント

作業負荷統計を収集する場合、作業負荷統計の一部として収集されたmbrcの値を使用して全表スキャンのコストを見積ることができます。ただし、作業負荷統計の収集プロセスでシリアル作業負荷の間に表スキャンが実行されない場合(OLTPシステムでしばしば発生します)、mbrcおよびmreadtimの値が収集されない場合があります。一方、DSSシステムでは全表スキャンが頻繁に実行されますが、パラレル実行によってバッファ・キャッシュがバイパスされる可能性があります。このような場合、バッファ・キャッシュを使用して索引参照が実行されるため、sreadtimの値が収集されます。

mbrcまたはmreadtimの値を収集できないか、または収集してもそれらの検証ができない場合で、sreadtimおよびcpuspeedの値が収集済の場合は、sreadtimおよびcpuspeedの値のみがコスト計算に使用されます。この場合、オプティマイザは初期化パラメータDB_FILE_MULTIBLOCK_READ_COUNTの値を使用して全表スキャンを見積ることができます。ただし、DB_FILE_MULTIBLOCK_READ_COUNTを設定しないか、0(ゼロ)に設定する場合、オプティマイザは値8を使用してコストを見積ります。

13.4.2 非作業負荷統計

非作業負荷統計は、I/O転送速度、I/Oシーク時間およびCPU速度(cpuspeednw)で構成されています。作業負荷統計と非作業負荷統計の主な違いは、収集方法にあります。

非作業負荷統計は、すべてのデータ・ファイルに対してランダム読取りを発行してデータを収集しますが、作業負荷統計は、データベース・アクティビティの発生時に更新されるカウンタを使用します。ioseektimは、ディスク・ヘッドがデータを読み取る位置に移動する時間を表します。この値は、ディスクの回転速度およびディスクまたはRAIDの仕様に応じて5ミリ秒〜15ミリ秒の間で変化します。I/O転送速度は、オペレーティング・システムの1つのプロセスでI/Oサブシステムからのデータの読取りが可能な速度を表します。この値は、毎秒数MBから数百MBまで大きく変化します。Oracleでは、I/O転送速度に比較的低い値のデフォルト設定を使用しています。

Oracle10gでは、非作業負荷統計およびCPUコスト・モデルをデフォルトで使用しています。非作業負荷統計の値は、最初のインスタンス起動時にデフォルトに初期化されます。

ioseektim = 10ms
iotrfspeed = 4096 bytes/ms
cpuspeednw = gathered value, varies based on system

作業負荷統計が収集されると非作業負荷統計は無視され、かわりに作業負荷統計が使用されます。

13.4.2.1 非作業負荷統計の収集

非作業負荷統計を収集するには、引数なしでdbms_stats.gather_system_stats()を実行します。非作業負荷統計の収集プロセスの間、I/Oシステムにオーバーヘッドが発生します。この収集プロセスは、I/Oのパフォーマンスおよびデータベースのサイズによって数秒から数分かかることがあります。

この情報は分析され、整合性が検証されます。場合により、非作業負荷統計の値はデフォルト値のままになることがあります。このような場合は、統計収集プロセスを繰り返すか、dbms_stats.set_system_statsプロシージャを使用してI/Oシステムの仕様に応じた値に手動で設定します。

13.5 統計の管理

この項では、次の内容を説明します。

13.5.1 統計の保留

11gリリース1(11.1)以上では、統計の収集時に、収集操作の最後に自動的に統計を公開するか(デフォルト動作)、またはその新規統計を保留中として保存するかを選択できます。新規統計を保留中として保存すると、新規統計を検証して、それらが適切である場合にのみ公開できます。

統計が収集直後に自動的に公開されるかどうかをチェックするには、次のようにDBMS_STATSパッケージを使用してPUBLISH属性の値を確認します。

Select dbms_stats.get_prefs('PUBLISH') publish from dual;

この問合せにより、TRUEまたはFALSEが戻されます。TRUEは統計が収集時に公開されることを示し、FALSEは統計が保留中として保存されることを示します。


注意:

公開された統計は、USER_TAB_STATISTICSUSER_IND_STATISTICSなどのデータ・ディクショナリ・ビューに格納されます。保留中の統計は、USER_TAB_PENDING_STATSUSER_IND_PENDING_STATSなどのビューに格納されます。

PUBLISH設定は、スキーマ・レベルまたは表レベルで変更できます。たとえば、SHスキーマのcustomers表のPUBLISH設定を変更するには、次の文を実行します。

Exec dbms_stats.set_table_prefs('SH', 'CUSTOMERS', 'PUBLISH', 'false');

これで、customers表の統計が収集される場合に、その統計は収集ジョブの完了時に自動的に公開されなくなります。かわりに、新規に収集された統計はUSER_TAB_PENDING_STATS表に格納されます。

デフォルトでは、オプティマイザはデータ・ディクショナリ・ビューに格納されている公開済の統計を使用します。新規に収集された保留中の統計をオプティマイザで使用する場合は、OPTIMIZER_USE_PENDING_STATISTICS初期化パラメータをTRUEに設定し(デフォルト値はFALSE)、表またはスキーマに対してワークロードを実行します。

alter session set optimizer_use_pending_statistics = TRUE;

オプティマイザでは、SQL文のコンパイル時に、公開済の統計のかわりに保留中の統計が使用されます。保留中の統計が有効である場合、次の文を実行することでそれらの統計を公開できます。

Exec dbms_stats.publish_pending_stats(null, null);

特定のデータベース・オブジェクトに関する保留中の統計を公開することもできます。たとえば、次の文を使用します。

Exec dbms_stats.publish_pending_stats('SH','CUSTOMERS');

保留中の統計を公開しない場合は、次の文を実行してそれらの統計を削除します。

Exec dbms_stats.delete_pending_stats('SH','CUSTOMERS');

保留中の統計は、dbms_stats.export_pending_statsファンクションを使用してエクスポートできます。保留中の統計をテスト・システムにエクスポートすると、新規統計に対してすべてのワークロードを実行できます。

13.5.2 前のバージョンの統計のリストア

ディクショナリ内で統計が変更されるたびに、後でリストアできるように前のバージョンの統計が自動的に保存されます。統計をリストアするには、DBMS_STATSパッケージのRESTOREプロシージャを使用します。これらのプロシージャは、引数としてタイムスタンプを使用し、そのタイムスタンプでの統計をリストアします。これは、新規に収集された統計では不適切な実行計画が作成され、管理者が前の統計セットに戻す必要がある場合に役立ちます。

統計の変更時刻を表示するディクショナリ・ビューがあります。これらのビューは、統計のリストアに使用するタイムスタンプを判断する場合に役立ちます。

  • カタログ・ビューDBA_OPTSTAT_OPERATIONSには、DBMS_STATSを使用してスキーマ・レベルとデータベース・レベルで実行された統計操作の履歴が含まれます。

  • *_TAB_STATS_HISTORYビュー(ALLDBAまたはUSER)には、表統計の変更履歴が含まれます。

古い統計は、統計履歴の保存設定とシステムの最終分析時刻に基づいて、定期的かつ自動的に消去されます。保存期間は、DBMS_STATSALTER_STATS_HISTORY_RETENTIONプロシージャを使用して構成可能です。デフォルト値は31日で、オプティマイザ統計を過去31日の任意の時点までリストアできることを意味します。

自動消去は、STATISTICS_LEVELパラメータがTYPICALまたはALLに設定されている場合に有効になります。自動消去が無効になっている場合は、PURGE_STATSプロシージャを使用して古いバージョンの統計を手動で消去する必要があります。

統計のリストアおよび消去に関連する他のDBMS_STATSプロシージャは、次のとおりです。

  • PURGE_STATS: このプロシージャを使用すると、タイムスタンプを超える古いバージョンを手動で消去できます。

  • GET_STATS_HISTORY_RETENTION: このファンクションを使用すると、現行の統計履歴の保存値を取得できます。

  • GET_STATS_HISTORY_AVAILABILTY: このファンクションを使用すると、統計履歴が使用可能な最も古いタイムスタンプを取得できます。最も古いタイムスタンプより前のタイムスタンプには、統計をリストアできません。

前のバージョンの統計をリストアする場合は、次の制限が適用されます。

  • RESTOREプロシージャでは、ユーザー定義統計はリストアできません。

  • 統計の収集にANALYZEコマンドが使用された場合、古いバージョンの統計は格納されません。


注意:

DBMS_STATSを使用するとき表からすべての行を削除する必要がある場合、同じ表を削除して再度作成するかわりに、TRUNCATEを使用します。表が削除されると、自動ヒストグラム収集機能が使用するワークロード情報と、RESTORE_*_STATSプロシージャが使用する保存された統計履歴が消失します。このデータなしでは、これらの機能は適切に動作しません。

13.5.3 統計のエクスポートとインポート

統計をデータ・ディクショナリからエクスポートして、ユーザー所有の表にインポートできます。これにより、同じスキーマについて複数バージョンの統計を作成できます。また、データベース間で統計のコピーもできます。この操作により、統計を本番データベースから小規模なテスト・データベースにコピーできます。


注意:

統計のエクスポートとインポートは、データベースのEXPおよびIMPユーティリティとは異なる概念です。DBMS_STATSエクスポートおよびインポート・パッケージでは、IMPおよびEXPダンプ・ファイルが使用されます。

統計をエクスポートする前に、その統計を保持する表を作成する必要があります。この統計表を作成するには、DBMS_STATS.CREATE_STAT_TABLEプロシージャを使用します。この表の作成後に、DBMS_STATS.EXPORT_*_STATSプロシージャを使用して、データ・ディクショナリから統計表に統計をエクスポートできます。その後、DBMS_STATS.IMPORT_*_STATSプロシージャを使用して統計をインポートします。

オプティマイザでは、ユーザー所有の表に格納されている統計が使用されないことに注意してください。オプティマイザで使用されるのは、データ・ディクショナリに格納されている統計のみです。ユーザー所有の表内の統計をオプティマイザで使用するには、統計インポート・プロシージャを使用して、その統計をデータ・ディクショナリにインポートする必要があります。

統計をデータベース間で移動するには、最初のデータベース上の統計をエクスポートしてから、EXPおよびIMPユーティリティまたは他のメカニズムを使用して統計表を第2のデータベースにコピーし、最後に統計を第2のデータベースにインポートする必要があります。


注意:

EXPおよびIMPユーティリティは、データベースから表とともにオプティマイザ統計をエクスポートおよびインポートします。ただし、表にシステム生成名を持つ列が含まれている場合、統計はデータとともにエクスポートされません。

13.5.4 統計のリストアとインポートまたはエクスポートの相違点

統計リストア機能は、ある面では統計のインポートおよびエクスポート機能に類似しています。通常、次の場合にはリストア機能を使用します。

  • 統計の古いバージョンをリカバリする場合。たとえば、オプティマイザの動作を前の日付までリストアする場合などです。

  • データベースで統計履歴の保存および消去を管理する場合。

次の場合には、EXPORT/IMPORT_*_STATSプロシージャを使用する必要があります。

  • 複数の統計セットを試験的に使用して値を増減させる場合。

  • データベース間で統計を移動する場合。たとえば、本番システムからテスト・システムに統計を移動する場合などです。

  • 既知の統計セットを統計のリストアに必要な保存日数よりも長期的に保持する場合。

13.5.5 表統計またはスキーマ統計のロック

表またはスキーマの統計をロックできます。統計がロックされると、その統計はロックが解除されるまで変更できなくなります。これらのロック・プロシージャは、統計が変化しないことを保証する必要のある静的環境に役立ちます。

DBMS_STATSパッケージには、ロックするための2つのプロシージャ(LOCK_SCHEMA_STATSおよびLOCK_TABLE_STATS)と、統計のロックを解除するための2つのプロシージャ(UNLOCK_SCHEMA_STATSおよびUNLOCK_TABLE_STATS)が用意されています。

13.5.6 統計の設定

SET_*_STATISTICSプロシージャを使用して、表、列、索引およびシステムの統計を設定できます。統計が不正確であったり一貫性がないとパフォーマンスが低下するため、この方法での統計の設定はお薦めしません。

13.5.7 動的サンプリングを使用した統計の見積り

動的サンプリングの目的は、述語の選択性および表と索引に関する統計のより正確な見積りを判断して、サーバーのパフォーマンスを改善することです。表と索引に関する統計には、表ブロック・カウント、適用可能な索引ブロック・カウント、表のカーディナリティおよび関連する結合列の統計が含まれます。正確に見積ると、より適切な実行計画がオプティマイザで作成できます。

動的サンプリングを使用すると、次の作業が可能になります。

  • 収集された統計が使用できない、あるいは見積りで重大なエラーを引き起こす可能性がある場合に、単一表の述語の選択性を見積ります。

  • 表、および統計のない関連索引に対する統計を見積ります。

  • 表、および統計が古すぎるために信頼できない関連索引に対する統計を見積ります。

この動的サンプリング機能は、OPTIMIZER_DYNAMIC_SAMPLINGパラメータにより制御されます。動的サンプリングにより必要な統計を自動的に収集するには、このパラメータを2以上の値に設定する必要があります。デフォルト値は2です。設定できるサンプリング・レベルの詳細は、「動的サンプリング・レベル」を参照してください。

13.5.7.1 動的サンプリングの動作

重要なパフォーマンス属性は、コンパイル時に決定されます。Oracleでは、問合せで動的サンプリングを使用する利点があるかどうか、コンパイル時に判別されます。利点がある場合、再帰的SQL文が発行されて表のブロックの小さなランダム・サンプルがスキャンされ、関連する単一表の述語を適用することで述語の選択性の見積りが行われます。サンプルしたカーディナリティが、表のカーディナリティの見積りに使用される場合もあります。関連する列統計情報と索引統計情報も収集されます。

OPTIMIZER_DYNAMIC_SAMPLING初期化パラメータの値によって、動的サンプリングの問合せで読み取られるブロック数が決定します。


関連項目:

この初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください。

13.5.7.2 動的サンプリング使用のタイミング

通常、迅速に(数秒以内で)完了する問合せに対しては、動的サンプリングのコストが発生するのは望ましくありません。しかし、次のいずれかの条件が当てはまる場合は、動的サンプリングが有効です。

  • 動的サンプリングを使用すると、より優れた計画になる場合。

  • サンプリングにかかる時間が、問合せの実行時間全体のごく一部である場合。

  • 問合せが何度も実行される場合。

動的サンプリングは、単一表の述語によるサブセットに適用したり、動的サンプリングが行われていない述語の通常の選択性の見積りと組み合せることができます。

13.5.7.3 動的サンプリングを使用したパフォーマンスの改善方法

動的サンプリングは、OPTIMIZER_DYNAMIC_SAMPLINGパラメータを使用して制御します。このパラメータの値は、010に設定できます。デフォルトは2です。

  • 値が0の場合、動的サンプリングが行われません。

  • パラメータの値が大きくなるにつれて、サンプリングされる表(分析された表、あるいは分析されていない表)のタイプについても、サンプリングで使用されるI/Oの量に関しても、動的サンプリングがより積極的に適用されるようになります。

動的サンプリングは、サンプリング対象の表内で行が挿入、削除または更新されていない場合、同じものが繰り返し使用されます。OPTIMIZER_FEATURES_ENABLEパラメータが9.2.0より前のリリースに設定されている場合、動的サンプリングはオフになります。

13.5.7.4 動的サンプリング・レベル

サンプリング・レベルは、使用された動的サンプリング・レベルがカーソル・ヒントまたはOPTIMIZER_DYNAMIC_SAMPLING初期化パラメータからの場合、次のようになります。

  • レベル0: 動的サンプリングは使用しないでください。

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

  • レベル2: 動的サンプリングをすべての分析されていない表に適用します。サンプリングされたブロック数は、動的サンプリングのブロックのデフォルト数の2倍です。

  • レベル3: レベル2の基準を満たすすべての表と、標準の選択性の見積りで動的サンプリングの可能性がある述語の推論が使用されるすべての表に、動的サンプリングを適用します。サンプリングされたブロック数は、動的サンプリングのブロックのデフォルト数です。分析されていない表の場合、サンプリングされたブロック数は、動的サンプリングのブロックのデフォルト数の2倍です。

  • レベル4: 動的サンプリングをレベル3の基準を満たすすべての表、および2つ以上の列を参照する単一表の述語を持つすべての表に適用します。サンプリングされたブロック数は、動的サンプリングのブロックのデフォルト数です。分析されていない表の場合、サンプリングされたブロック数は、動的サンプリングのブロックのデフォルト数の2倍です。

  • レベル5、6、7、8および9: それぞれ動的サンプリング・ブロックのデフォルトの数の2、4、8、32または128倍を使用して、動的サンプリングを直前レベルの基準を満たすすべての表に適用します。

  • レベル10: 表内のすべてのブロックを使用して、動的サンプリングをレベル9の基準を満たすすべての表に適用します。

表の動的サンプリング・レベルがDYNAMIC_SAMPLINGオプティマイザ・ヒントを使用して設定されている場合のサンプリング・レベルは、次のとおりです。

  • レベル0: 動的サンプリングは使用しないでください。

  • レベル1: サンプリングされたブロック数は、動的サンプリングのブロックのデフォルト数です(32)。

  • レベル2、3、4、5、6、7、8および9: サンプリングされたブロック数は、それぞれ動的サンプリング・ブロックのデフォルト数の2、4、8、16、32、64、128または256倍です。

  • レベル10: 表内のすべてのブロックを読み取ります。


    関連項目:

    DYNAMIC_SAMPLINGヒントを使用してサンプリング・レベルを設定する方法については、『Oracle Database SQL言語リファレンス』を参照してください。

13.5.8 統計の欠落の処理

Oracleでは、統計が欠落している表が検出されると、オプティマイザに必要な統計が動的に収集されます。ただし、ある種の表の場合、動的サンプリングは実行されません。これには、リモート表と外部表が含まれます。これらの場合および動的サンプリングが無効になっている場合、オプティマイザは統計にデフォルト値を使用します。表13-7および表13-8を参照してください。

表13-7 統計が欠落しているときの表のデフォルト値

表統計 オプティマイザによって使用されるデフォルト値

カーディナリティ

ブロック数×(ブロック・サイズ - キャッシュ層)÷行の平均の長さ

行の平均長さ

100バイト

ブロック数

100、またはエクステント・マップに基づく実際の値

リモート・カーディナリティ

2000行

リモートの行の平均長さ

100バイト


表13-8 統計が欠落しているときの索引のデフォルト値

索引統計 オプティマイザによって使用されるデフォルト値

レベル

1

リーフ・ブロック

25

リーフ・ブロック/キー

1

データ・ブロック/キー

1

個別キー

100

クラスタ化係数

800


13.6 統計の表示

この項では、次の内容を説明します。

13.6.1 表、索引および列の統計

表、索引および列の統計は、データ・ディクショナリに格納されます。データ・ディクショナリ内の統計を表示するには、適切なデータ・ディクショナリ・ビューを問い合せます(USERALLまたはDBA)。次のDBA_*ビューがあります。

  • DBA_TABLES

  • DBA_OBJECT_TABLES

  • DBA_TAB_STATISTICS

  • DBA_TAB_COL_STATISTICS

  • DBA_TAB_HISTOGRAMS

  • DBA_TAB_COLS

  • DBA_COL_GROUP_COLUMNS

  • DBA_INDEXES

  • DBA_IND_STATISTICS

  • DBA_CLUSTERS

  • DBA_TAB_PARTITIONS

  • DBA_TAB_SUBPARTITIONS

  • DBA_IND_PARTITIONS

  • DBA_IND_SUBPARTITIONS

  • DBA_PART_COL_STATISTICS

  • DBA_PART_HISTOGRAMS

  • DBA_SUBPART_COL_STATISTICS

  • DBA_SUBPART_HISTOGRAMS


関連項目:

これらのビューの統計の詳細は、『Oracle Databaseリファレンス』を参照してください。

13.6.2 ヒストグラムの表示

列統計情報はヒストグラムとして格納できます。これらのヒストグラムは、列データの配分の正確な見積りを提供します。ヒストグラムによって、データが偏っている場合の選択性の見積りの精度が改善され、均一でないデータ配分が存在する最適な実行計画が得られます。

Oracleでは、列統計に次のタイプのヒストグラムを使用します。

ヒストグラムのタイプは、*TAB_COL_STATISTICSビュー(USERおよびDBA)のHISTOGRAM列に格納されます。この列の値は、HEIGHT BALANCEDFREQUENCYまたはNONEです。

13.6.2.1 高さ調整済ヒストグラム

高さ調整済ヒストグラムでは、列値が帯域に分割され、各帯域にほぼ同数の行が存在するようになっています。したがって、ヒストグラムによって提示される有用な情報が存在するのは、値範囲のエンドポイントが位置するところです。

値が1〜100の間に存在し、ヒストグラムが10バケットである列Cについて検討します。Cのデータ配分が均一な場合のヒストグラムは、図13-1のようになります。数字はエンドポイントの値です。

図13-1 データ配分が均一の高さ調整済ヒストグラム

図13-1の説明が続きます。
「図13-1 データ配分が均一の高さ調整済ヒストグラム」の説明

各バケット内の行数は、表内の全行数の10分の1です。均一に分布しているこの例では、4/10の行の値が、60〜100の間にあります。

データ配分が均一でない場合のヒストグラムは、図13-2のようになります。

図13-2 データ配分が非均一の高さ調整済ヒストグラム

図13-2の説明が続きます。
「図13-2 データ配分が非均一の高さ調整済ヒストグラム」の説明

この場合、ほとんどの行で、この列の値が5になっています。60〜100の間の値を持っている行は、行全体の1/10のみです。

高さ調整済ヒストグラムは、例13-1に示すように*TAB_HISTOGRAMS表を使用して表示できます。

例13-1 高さ調整済ヒストグラム統計の表示

BEGIN
  DBMS_STATS.GATHER_table_STATS (OWNNAME => 'OE', TABNAME => 'INVENTORIES',
  METHOD_OPT => 'FOR COLUMNS SIZE 10 quantity_on_hand');
END;
/

SELECT column_name, num_distinct, num_buckets, histogram
  FROM USER_TAB_COL_STATISTICS
 WHERE table_name = 'INVENTORIES' AND column_name = 'QUANTITY_ON_HAND';

COLUMN_NAME                    NUM_DISTINCT NUM_BUCKETS HISTOGRAM
------------------------------ ------------ ----------- ---------------
QUANTITY_ON_HAND                        237          10 HEIGHT BALANCED

SELECT endpoint_number, endpoint_value
  FROM USER_HISTOGRAMS
 WHERE table_name = 'INVENTORIES' and column_name = 'QUANTITY_ON_HAND'
  ORDER BY endpoint_number;

ENDPOINT_NUMBER ENDPOINT_VALUE
--------------- --------------
              0              0
              1             27
              2             42
              3             57
              4             74
              5             98
              6            123
              7            149
              8            175
              9            202
             10            353

問合せ出力では、ヒストグラム内で1行が1つのバケットに対応します。

13.6.2.2 頻度ヒストグラム

頻度ヒストグラムでは、列の値がそれぞれヒストグラムの1つのバケットに対応します。各バケットには、その単一値の発生数が含まれます。個別値の個数が、指定されたヒストグラム・バケットの個数以下であれば、高さ調整済ヒストグラムのかわりに頻度ヒストグラムが自動的に作成されます。頻度ヒストグラムは、例13-2に示すように*TAB_HISTOGRAMSビューを使用して表示できます。

例13-2 頻度ヒストグラム統計の表示

BEGIN
  DBMS_STATS.GATHER_table_STATS (OWNNAME => 'OE', TABNAME => 'INVENTORIES',
  METHOD_OPT => 'FOR COLUMNS SIZE 20 warehouse_id');
END;
/

SELECT column_name, num_distinct, num_buckets, histogram
FROM   USER_TAB_COL_STATISTICS
WHERE  table_name = 'INVENTORIES'
AND    column_name = 'WAREHOUSE_ID';

COLUMN_NAME                    NUM_DISTINCT NUM_BUCKETS HISTOGRAM
------------------------------ ------------ ----------- ---------------
WAREHOUSE_ID                              9           9 FREQUENCY

SELECT   endpoint_number, endpoint_value
FROM     USER_HISTOGRAMS
WHERE    table_name = 'INVENTORIES'
AND      column_name = 'WAREHOUSE_ID'
ORDER BY endpoint_number;

ENDPOINT_NUMBER ENDPOINT_VALUE
--------------- --------------
             36              1
            213              2
            261              3
            370              4
            484              5
            692              6
            798              7
            984              8
           1112              9