この章では、問合せオプティマイザにとって統計が重要である理由、およびDBMS_STATS
パッケージを使用したオプティマイザ統計の収集方法と使用方法を説明します。
この章には次の項があります。
オプティマイザ統計は、データベースとそのオブジェクトに関する詳細情報を記述するデータの集合です。これらの統計は、問合せオプティマイザで各SQL文に最適の実行計画を選択するために使用されます。オプティマイザ統計には次のものがあります。
表統計
行数
ブロック数
行の平均長さ
列統計情報
列内の個別値(NDV)数
列内のNULL数
データ配分(ヒストグラム)
拡張統計
索引統計
リーフ・ブロック数
レベル
クラスタ化係数
システム統計
I/Oパフォーマンスと使用率
CPUパフォーマンスと使用率
注意: この項で説明する統計は、問合せを最適化する目的で作成されてデータ・ディクショナリに格納されるオプティマイザ統計です。この種の統計をV$ ビューで参照可能なパフォーマンス統計と混同しないでください。 |
オプティマイザ統計はデータ・ディクショナリに格納されます。また、データ・ディクショナリ・ビューを使用して表示できます。「統計の表示」を参照してください。
データベース内のオブジェクトは常に変化するため、これらのデータベース・オブジェクトが正確に記述されるように統計を定期的に更新する必要があります。統計はOracleにより自動的にメンテナンスされます。また、DBMS_STATS
パッケージを使用するとオプティマイザ統計を手動でメンテナンスできます。自動プロセスと手動プロセスについては、「自動オプティマイザ統計収集」または「手動統計収集」を参照してください。
DBMS_STATS
パッケージにも、統計を管理するためのプロシージャが用意されています。統計のコピーを保存してリストアできます。あるシステムから統計をエクスポートし、別のシステムにインポートできます。たとえば、本番システムからテスト・システムに統計をエクスポートできます。また、統計が変更されないようにロックすることも可能です。ロック方法の詳細は、「表統計またはスキーマ統計のロック」を参照してください。
推奨されるオプティマイザ統計収集方法は、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
プロシージャでは、統計を必要とするデータベース・オブジェクトに優先順位が設定されるため、更新済の統計を最も必要とするオブジェクトが最初に処理されることです。これにより、メンテナンス・ウィンドウがクローズする前に、最も必要性の高い統計が確実に収集されます。
自動オプティマイザ統計収集により、問合せオプティマイザの管理に関連する多数の手動タスクが不要になり、統計の欠落または失効が原因で不適切な実行計画が生成されるリスクが大幅に低下します。
この項では、次の項目について説明します。
オプティマイザ統計は、統計が失効または欠落しているデータベースのすべてのオブジェクトに関する統計を収集する自動オプティマイザ統計収集によって自動的に収集されます。自動オプティマイザ統計収集は、自動化メンテナンス・タスク・インフラストラクチャ(自動タスク)の一部として実行されます。この機能は、事前定義されたすべてのメンテナンス・ウィンドウで実行されるようデフォルトで有効化されています。
なんらかの理由で自動オプティマイザ統計収集が無効になった場合、次のように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
です。
関連項目:
|
この項では、次の内容を説明します。
普通の速度で変更されるほとんどのデータベース・オブジェクトの場合は、自動オプティマイザ統計収集で十分です。ただし、自動オプティマイザ統計収集では不十分な場合があります。自動オプティマイザ統計収集はメンテナンス・ウィンドウ中に実行されるため、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_STATS
、GATHER_DATABASE_STATS
および自動オプティマイザ統計収集処理中には統計は収集されません。ただし、GATHER_TABLE_STATS
を使用すると外部表の統計を個別に収集できます。外部表のサンプリングはサポートされていないため、ESTIMATE_PERCENT
オプションは明示的にNULL
に設定する必要があります。外部表のデータ操作は許可されないため、対応するファイルに変更があったときに外部表を分析すれば十分です。
STATISTICS_LEVEL
をBASIC
に設定して監視機能を無効にすると、自動オプティマイザ統計収集では失効している統計を検出できません。この場合は、統計を手動で収集する必要があります。自動監視機能の詳細は、「失効している統計の判別」を参照してください。
システム統計も、手動で収集する必要があります。この種の統計は自動的には収集されません。詳細は、「システム統計」を参照してください。
動的パフォーマンス表など、固定オブジェクトの統計は、GATHER_FIXED_OBJECTS_STATS
プロシージャを使用して手動で収集する必要があります。固定オブジェクトには現行のデータベース・アクティビティが記録されます。データベースに典型的なアクティビティがあるときに統計を収集する必要があります。
ディクショナリ内で統計が変更されるたびに、後でリストアできるように前のバージョンの統計が自動的に保存されます。統計をリストアするには、DBMS_STATS
パッケージのRESTORE
プロシージャを使用します。詳細は、「前のバージョンの統計のリストア」を参照してください。
「手動統計を使用する場合」で説明したように、揮発性の高い表など、表またはスキーマに関してDBMS_STATS_JOB
プロセスによる新規統計の収集を中止する必要がある場合があります。このような場合は、DBMS_STATS
パッケージに表またはスキーマの統計をロックするためのプロシージャが用意されています。詳細は、「表統計またはスキーマ統計のロック」を参照してください。
自動オプティマイザ統計収集を使用しないように選択した場合は、システム・スキーマを含め、すべてのスキーマ内で統計を手動で収集する必要があります。データベース内のデータが定期的に変化する場合は、統計がデータベース・オブジェクトの特性を正確に表すように、統計も定期的に収集する必要があります。
統計はDBMS_STATS
パッケージを使用して収集されます。このPL/SQLパッケージは、統計の変更、表示、エクスポート、インポートおよび削除にも使用されます。
DBMS_STATS
パッケージでは、表と索引の統計、および表の列とパーティションの個別の統計を収集できます。クラスタ統計は収集できません。ただし、DBMS_STATS
を使用して、全クラスタのかわりに個別の表の統計を収集できます。
表、列または索引の統計を生成するとき、分析したオブジェクトの統計がすでにデータ・ディクショナリ内に収録されている場合、Oracleは既存の統計を更新します。古い統計は保存され、後で必要に応じてリストアできます。「前のバージョンの統計のリストア」を参照してください。
システム・スキーマの統計を収集する場合は、DBMS_STATS.GATHER_DICTIONARY_STATS
プロシージャを使用できます。このプロシージャでは、SYS
やSYSTEM
を含むすべてのシステム・スキーマと、CTXSYS
やDRSYS
などの他のオプション・スキーマの統計が収集されます。
データベース・オブジェクトの統計が更新されると、そのオブジェクトにアクセスする現在解析済のSQL文が無効にされます。文が次に実行されるときに、文が再解析され、オプティマイザは新しい統計に基づいて新しい実行計画を自動的に選択します。リモート・データベース上で新しい統計を持つオブジェクトにアクセスする分散型の文は、無効にされません。新しい統計は、次回にSQL文が解析されると有効になります。
表13-1に、DBMS_STATS
パッケージにおけるデータベース・オブジェクトの統計収集のためのプロシージャを示します。
表13-1 DBMS_STATSパッケージの統計収集プロシージャ
プロシージャ | 収集対象 |
---|---|
索引統計 |
|
表、列および索引の統計 |
|
スキーマ内のすべてのオブジェクトの統計 |
|
すべてのディクショナリ・オブジェクトの統計 |
|
データベース内のすべてのオブジェクトの統計 |
関連項目: すべてのDBMS_STATS プロシージャの構文と例については、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
前述のプロシージャを統計収集に使用する場合は、次のようにいくつか重要な考慮事項があります。
統計収集操作では、サンプリングを使用して統計を予測できます。サンプリングは、統計収集の重要なテクニックです。サンプリングを使用せずに統計を収集するには、全表スキャンと表全体のソートが必要です。サンプリングを使用すると、統計収集に必要なリソースが最小限に抑えられます。
サンプリングは、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
収集プロシージャによりサンプリング率が自動的に増加されます。これによって、見積り値の変動が少なくなり、安定性が保証されます。
統計の収集操作は、シリアルまたはパラレルのどちらでも実行できます。並列度は、DBMS_STATS
収集プロシージャのDEGREE
引数で指定できます。パラレル統計収集はサンプリングと併用できます。DEGREE
パラメータをDBMS_STATS.AUTO_DEGREE
に設定することをお薦めします。このように設定すると、Oracleはオブジェクトのサイズとパラレル関連のinit.ora
パラメータの設定に基づいて適切な並列度を選択できます。
クラスタ索引、ドメイン索引およびビットマップ結合索引など、特定のタイプの索引統計は、パラレルでは収集されないことに注意してください。
パーティション表および索引に対して、DBMS_STATS
は、各パーティションの個別の統計を収集できます。また、全表または全索引のグローバル統計も収集できます。コンポジット・パーティションについても同様に、DBMS_STATS
はサブパーティション、パーティション、全表および全索引の個別の統計を収集できます。収集するパーティション統計のタイプは、DBMS_STATS
収集プロシージャのGRANULARITY
引数で指定します。
最適化されたSQL文によっては、オプティマイザがパーティション(サブパーティション)統計またはグローバル統計の使用を選択する場合があります。どちらのタイプの統計もほとんどのアプリケーションにとって重要であり、GRANULARITY
パラメータをAUTO
に設定して両方のタイプのパーティション統計を収集することをお薦めします。
パーティション表では、通常、新規データは新規パーティションにロードされます。新規パーティションの追加とデータのロードに合せ、統計は新規パーティションで収集する必要があり、グローバル統計は最新の状態に維持する必要があります。パーティション表のINCREMENTAL
値がTRUE
に設定され、GRANULARITY
パラメータがAUTO
に設定された状態でその表の統計を収集すると、Oracleでは、(表全体ではなく)変更済のパーティションのみがスキャンされ、新規パーティションの統計収集とグローバル表統計の更新が行われます。パーティション表のINCREMENTAL
値がFALSE
(デフォルト値)に設定されている場合、グローバル統計の維持には全表スキャンが使用されます。大規模な表では、これは大量にリソースを消費し、時間のかかる操作です。
注意: パーティション表でINCREMENTAL をTRUE に設定すると、SYSAUX 表領域ではグローバル統計を維持するために追加の領域が使用されます。
パーティション表の |
表の統計を収集する場合、DBMS_STATS
では表内の列のデータ配分情報が収集されます。データ配分に関して最も基本的な情報は、列の最大値と最小値です。ただし、列のデータに偏りがある場合、このレベルの統計ではオプティマイザのニーズが十分に満たされない場合があります。データ配分に偏りがある場合は、指定した列のデータ配分を記述するヒストグラムも列統計の一部として作成できます。ヒストグラムの詳細は、「ヒストグラムの表示」を参照してください。
ヒストグラムは、DBMS_STATS
収集プロシージャのMETHOD_OPT
引数を使用して指定します。METHOD_OPT
はFOR ALL COLUMNS SIZE AUTO
に設定することをお薦めします。この設定では、どの列にヒストグラムが必要であるかということと各ヒストグラムのバケット数(サイズ)が、Oracleにより自動的に判別されます。また、これらの情報は手動でも指定できます。
注意: DBMS_STATS を使用するとき表からすべての行を削除する必要がある場合、同じ表を削除して再度作成するかわりに、TRUNCATE を使用します。表が削除されると、自動ヒストグラム収集機能が使用するワークロード情報と、RESTORE_*_STATS プロシージャが使用する保存された統計履歴が消失します。このデータなしでは、これらの機能は適切に動作しません。 |
単一表の複数列が問合せのwhere
句で組み合されて使用される場合(複数の単一列条件)、列と列の間の関係が、その列グループの組合せ選択に大きな影響を与える可能性があります。
例として、SH
スキーマのcustomers
表を検討します。cust_state_province
列とcountry_id
列は、各顧客のcust_state_province
がcountry_id
を決定するという関係にあります。次のように、cust_state_province
がCalifornia
であるという条件で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
パッケージを使用して手動で列グループを作成することもできます。このパッケージを使用すると、列グループの作成、列グループ名の取得、または表からの列グループの削除が可能になります。
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; /
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
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)');
ディクショナリ表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
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');
注意: オプティマイザでは、等価述語で複数列の統計のみが使用されます。 |
問合せのwhere
句で列に関数が適用される場合(function(col1)=constant
)、オプティマイザでは、その関数が列の選択性に与える影響を認識できません。式function(col1)
に関する式の統計を収集することで、オプティマイザではより正確な選択値を特定できます。
このような関数の例は、次のとおりです。
SELECT COUNT(*) FROM CUSTOMERS WHERE LOWER(CUST_STATE_PROVINCE)='CA';
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;
ディクショナリ表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
データベース・オブジェクトは時間の経過につれて変更されるため、その統計を定期的に収集する必要があります。特定のデータベース・オブジェクトに新規データベース統計が必要かどうかを判別するために、Oracleには表監視機能が用意されています。この監視機能は、STATISTICS_LEVEL
がTYPICAL
またはALL
に設定されている場合にデフォルトで有効になります。監視では、最新の統計収集以降の、表に対するINSERT
、UPDATE
およびDELETE
の概数と、その表が切り捨てられているかどうかを追跡します。表の変更情報は、USER_TAB_MODIFICATIONS
ビューで表示できます。データ変更後は、このビューに情報が伝播するまでに数分の遅延が発生することがあります。メモリーに保存されている未処理の監視情報を即時に反映させるには、DBMS_STATS.FLUSH_DATABASE_MONITORING_INFO
プロシージャを使用します。
OPTIONS
パラメータをGATHER STALE
またはGATHER AUTO
に設定すると、GATHER_DATABASE_STATS
またはGATHER_SCHEMA_STATS
プロシージャは、統計が失効している表に関して新規の統計を収集します。監視される表の変更が10%を超えた場合、これらの統計は失効したものとみなされ、再度収集されます。
ユーザー定義のオプティマイザ統計を作成して、ユーザー定義の索引およびファンクションをサポートできます。統計タイプを列またはドメイン索引に対応付ける場合、データベース・オブジェクトの統計が収集されるたびに、Oracleでは統計タイプの統計コレクション・メソッドがコールされます。
Oracleにより式が表すのと同等の列統計情報を収集できるように、ファンクション索引の作成後に表の新規列統計を収集する必要があります。そのためには、METHOD_OPT
引数をFOR ALL HIDDEN COLUMNS
に設定して統計収集プロシージャをコールします。
関連項目: ユーザー定義統計の実装の詳細は、『Oracle Databaseデータ・カートリッジ開発者ガイド』を参照してください。 |
統計を手動で収集する場合は、その収集方法を決定するのみでなく、新規統計の収集時期と頻度も決定する必要があります。
表の増分変更が行われるアプリケーションの場合は、新規の統計を週または月に1回収集するのみでよい場合があります。このような環境で最も簡単な統計収集方法は、スクリプトまたはジョブ・スケジューリング・ツールを使用して、GATHER_SCHEMA_STATS
およびGATHER_DATABASE_STATS
プロシージャを定期的に実行することです。収集の頻度によって、統計収集プロセスで起こるオーバーヘッドの処理に対し、オプティマイザの正確な統計を出すタスクのバランスをとります。
バルク・ロードを使用する場合など、バッチ操作で逐次変更される表の場合は、その表の統計をバッチ操作の一部として収集する必要があります。ロード操作の完了直後にDBMS_STATS
プロシージャをコールしてください。
パーティション表の場合、通常は1つのパーティションのみが変更されます。このような場合は、表全体の統計を収集するのではなく、変更があったパーティションの統計のみを収集できます。ただし、パーティション表のグローバル統計の収集も必要な場合があります。
関連項目: DBMS_STATS パッケージのGATHER_SCHEMA_STATS およびGATHER_DATABASE_STATS プロシージャの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
DBMS_STATS
を使用すると、2つの異なるソースの表の統計を比較できます。表13-5に、統計を比較するためのDBMS_STATS
パッケージのファンクションを示します。
表13-5 統計を比較するDBMS_STATSパッケージのファンクション
プロシージャ | 比較対象 |
---|---|
保留中の統計とタイムスタンプの時点の統計またはディクショナリの統計 |
|
2つの異なるソースの表の統計 |
|
過去の2つのタイムスタンプからの表の統計、およびそれらのタイムスタンプの時点の統計 |
表13-5のファンクションでは、索引、列およびパーティションなどの依存オブジェクトの統計も比較します。これらの統計間の差分が特定のしきい値を超える場合、両方のソースのオブジェクトの統計が表示されます。ファンクションの引数としてしきい値を指定できます。デフォルトは10%です。Oracle Databaseでは、最初のソースに相当する統計を基本として使用し、異なる割合を計算します。
関連項目: DBMS_STATS パッケージのDIFF_TABLE_STATS_* ファンクションの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
システム統計は、問合せオプティマイザに対してシステムのハードウェア特性(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パッケージ内のオプティマイザのシステム統計
パラメータ名 | 説明 | 初期化 | 統計の収集または設定のオプション | 単位 |
---|---|---|---|---|
|
作業負荷のない場合のCPU速度を表します。CPU速度は、1秒当たりのCPU平均サイクル数です。 |
システム起動時 |
|
100万/秒 |
|
I/Oシーク時間は、シーク時間、待機時間およびオペレーティング・システム・オーバーヘッド時間を合計したものです。 |
システム起動時 10(デフォルト) |
|
ミリ秒 |
|
I/O転送速度は、1回の読取りリクエストでOracleデータベースがデータを読み取ることができる速度です。 |
システム起動時 4096(デフォルト) |
|
バイト/ミリ秒 |
|
作業負荷をかけた場合のCPU速度を表します。CPU速度は、1秒当たりのCPU平均サイクル数です。 |
なし |
|
100万/秒 |
|
最大I/Oスループットは、I/Oサブシステムが発揮できる最大スループットです。 |
なし |
|
バイト/秒 |
|
スレーブI/Oスループットは、パラレル・スレーブの平均I/Oスループットです。 |
なし |
|
バイト/秒 |
|
単一ブロック読取り時間は、単一ブロックをランダムに読み取る平均時間です。 |
なし |
|
ミリ秒 |
|
マルチブロック読取りは、マルチブロックを順に読み取る平均時間です。 |
なし |
|
ミリ秒 |
|
マルチブロック・カウントは、平均マルチブロック順次読取りカウントです。 |
なし |
|
ブロック |
表、索引、列の統計とは異なり、システム統計の更新時には、すでに解析されているSQL文は無効にされません。新しいSQL文はすべて、新しい統計を使用して解析されます。
システム統計の収集方法には2つのオプションがあります。
これらのオプションは、物理データベースおよび作業負荷の収集プロセスを容易に使用できるようにします。作業負荷システム統計が収集されると、非作業負荷システム統計は無視されます。非作業負荷システム統計は、データベースの初回の起動時にデフォルト値に初期化されます。
関連項目: システム統計を実装するためのDBMS_STATS パッケージのプロシージャの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
Oracle9iで導入された作業負荷統計は、シングルおよびマルチブロックの読取り時間、mbrc
、CPU速度(cpuspeed
)、最大システム・スループットおよび平均スレーブ・スループットを収集します。sreadtim
、mreadtim
およびmbrc
は、作業負荷の開始から終了までの2点間の、物理的な順次およびランダム読取りの数を比較して計算されます。これらの値は、バッファ・キャッシュが同期読取りリクエストを完了したときに変更されるカウンタを通して実装されます。このカウンタはバッファ・キャッシュ内にあるため、これらにはI/O遅延のみならず、ラッチの競合およびタスク・スイッチングに関連する待機も含まれています。このように、作業負荷統計は、作業負荷ウィンドウでシステムが実行するアクティビティに応じて異なります。ラッチ競合およびI/Oスループットの両方でシステムがI/Oバウンドの場合、この状態は統計に反映され、この統計が使用された後でI/O低減化集中計画が促進されます。さらに、作業負荷統計収集は、追加のオーバーヘッドを生成しません。
リリース9.2では、全表スキャン(FTS)の下限を設定するための最大I/Oスループットおよび平均スレーブ・スループットが追加されました。
作業負荷統計を収集するには、次のいずれかの手順を実行します。
作業負荷ウィンドウの開始時に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()
を実行します。作業負荷統計が削除され、デフォルトの非作業負荷統計にリセットされます。
作業負荷統計を収集する場合、作業負荷統計の一部として収集されたmbrc
の値を使用して全表スキャンのコストを見積ることができます。ただし、作業負荷統計の収集プロセスでシリアル作業負荷の間に表スキャンが実行されない場合(OLTPシステムでしばしば発生します)、mbrc
およびmreadtim
の値が収集されない場合があります。一方、DSSシステムでは全表スキャンが頻繁に実行されますが、パラレル実行によってバッファ・キャッシュがバイパスされる可能性があります。このような場合、バッファ・キャッシュを使用して索引参照が実行されるため、sreadtim
の値が収集されます。
mbrc
またはmreadtim
の値を収集できないか、または収集してもそれらの検証ができない場合で、sreadtim
およびcpuspeed
の値が収集済の場合は、sreadtim
およびcpuspeed
の値のみがコスト計算に使用されます。この場合、オプティマイザは初期化パラメータDB_FILE_MULTIBLOCK_READ_COUNT
の値を使用して全表スキャンを見積ることができます。ただし、DB_FILE_MULTIBLOCK_READ_COUNT
を設定しないか、0(ゼロ)に設定する場合、オプティマイザは値8を使用してコストを見積ります。
非作業負荷統計は、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
作業負荷統計が収集されると非作業負荷統計は無視され、かわりに作業負荷統計が使用されます。
非作業負荷統計を収集するには、引数なしでdbms_stats.gather_system_stats()
を実行します。非作業負荷統計の収集プロセスの間、I/Oシステムにオーバーヘッドが発生します。この収集プロセスは、I/Oのパフォーマンスおよびデータベースのサイズによって数秒から数分かかることがあります。
この情報は分析され、整合性が検証されます。場合により、非作業負荷統計の値はデフォルト値のままになることがあります。このような場合は、統計収集プロセスを繰り返すか、dbms_stats.set_system_stats
プロシージャを使用してI/Oシステムの仕様に応じた値に手動で設定します。
この項では、次の内容を説明します。
11gリリース1(11.1)以上では、統計の収集時に、収集操作の最後に自動的に統計を公開するか(デフォルト動作)、またはその新規統計を保留中として保存するかを選択できます。新規統計を保留中として保存すると、新規統計を検証して、それらが適切である場合にのみ公開できます。
統計が収集直後に自動的に公開されるかどうかをチェックするには、次のようにDBMS_STATS
パッケージを使用してPUBLISH
属性の値を確認します。
Select dbms_stats.get_prefs('PUBLISH') publish from dual;
この問合せにより、TRUE
またはFALSE
が戻されます。TRUE
は統計が収集時に公開されることを示し、FALSE
は統計が保留中として保存されることを示します。
注意: 公開された統計は、USER_TAB_STATISTICS やUSER_IND_STATISTICS などのデータ・ディクショナリ・ビューに格納されます。保留中の統計は、USER_TAB_PENDING_STATS やUSER_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
ファンクションを使用してエクスポートできます。保留中の統計をテスト・システムにエクスポートすると、新規統計に対してすべてのワークロードを実行できます。
ディクショナリ内で統計が変更されるたびに、後でリストアできるように前のバージョンの統計が自動的に保存されます。統計をリストアするには、DBMS_STATS
パッケージのRESTORE
プロシージャを使用します。これらのプロシージャは、引数としてタイムスタンプを使用し、そのタイムスタンプでの統計をリストアします。これは、新規に収集された統計では不適切な実行計画が作成され、管理者が前の統計セットに戻す必要がある場合に役立ちます。
統計の変更時刻を表示するディクショナリ・ビューがあります。これらのビューは、統計のリストアに使用するタイムスタンプを判断する場合に役立ちます。
カタログ・ビューDBA_OPTSTAT_OPERATIONS
には、DBMS_STATS
を使用してスキーマ・レベルとデータベース・レベルで実行された統計操作の履歴が含まれます。
*_TAB_STATS_HISTORY
ビュー(ALL
、DBA
またはUSER
)には、表統計の変更履歴が含まれます。
古い統計は、統計履歴の保存設定とシステムの最終分析時刻に基づいて、定期的かつ自動的に消去されます。保存期間は、DBMS_STATS
のALTER_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 プロシージャが使用する保存された統計履歴が消失します。このデータなしでは、これらの機能は適切に動作しません。 |
統計をデータ・ディクショナリからエクスポートして、ユーザー所有の表にインポートできます。これにより、同じスキーマについて複数バージョンの統計を作成できます。また、データベース間で統計のコピーもできます。この操作により、統計を本番データベースから小規模なテスト・データベースにコピーできます。
注意: 統計のエクスポートとインポートは、データベースのEXP およびIMP ユーティリティとは異なる概念です。DBMS_STATS エクスポートおよびインポート・パッケージでは、IMP およびEXP ダンプ・ファイルが使用されます。 |
統計をエクスポートする前に、その統計を保持する表を作成する必要があります。この統計表を作成するには、DBMS_STATS.CREATE_STAT_TABLE
プロシージャを使用します。この表の作成後に、DBMS_STATS.EXPORT_*_STATS
プロシージャを使用して、データ・ディクショナリから統計表に統計をエクスポートできます。その後、DBMS_STATS.IMPORT_*_STATS
プロシージャを使用して統計をインポートします。
オプティマイザでは、ユーザー所有の表に格納されている統計が使用されないことに注意してください。オプティマイザで使用されるのは、データ・ディクショナリに格納されている統計のみです。ユーザー所有の表内の統計をオプティマイザで使用するには、統計インポート・プロシージャを使用して、その統計をデータ・ディクショナリにインポートする必要があります。
統計をデータベース間で移動するには、最初のデータベース上の統計をエクスポートしてから、EXP
およびIMP
ユーティリティまたは他のメカニズムを使用して統計表を第2のデータベースにコピーし、最後に統計を第2のデータベースにインポートする必要があります。
統計リストア機能は、ある面では統計のインポートおよびエクスポート機能に類似しています。通常、次の場合にはリストア機能を使用します。
統計の古いバージョンをリカバリする場合。たとえば、オプティマイザの動作を前の日付までリストアする場合などです。
データベースで統計履歴の保存および消去を管理する場合。
次の場合には、EXPORT/IMPORT_*_STATS
プロシージャを使用する必要があります。
複数の統計セットを試験的に使用して値を増減させる場合。
データベース間で統計を移動する場合。たとえば、本番システムからテスト・システムに統計を移動する場合などです。
既知の統計セットを統計のリストアに必要な保存日数よりも長期的に保持する場合。
表またはスキーマの統計をロックできます。統計がロックされると、その統計はロックが解除されるまで変更できなくなります。これらのロック・プロシージャは、統計が変化しないことを保証する必要のある静的環境に役立ちます。
DBMS_STATS
パッケージには、ロックするための2つのプロシージャ(LOCK_SCHEMA_STATS
およびLOCK_TABLE_STATS
)と、統計のロックを解除するための2つのプロシージャ(UNLOCK_SCHEMA_STATS
およびUNLOCK_TABLE_STATS
)が用意されています。
SET_*_STATISTICS
プロシージャを使用して、表、列、索引およびシステムの統計を設定できます。統計が不正確であったり一貫性がないとパフォーマンスが低下するため、この方法での統計の設定はお薦めしません。
動的サンプリングの目的は、述語の選択性および表と索引に関する統計のより正確な見積りを判断して、サーバーのパフォーマンスを改善することです。表と索引に関する統計には、表ブロック・カウント、適用可能な索引ブロック・カウント、表のカーディナリティおよび関連する結合列の統計が含まれます。正確に見積ると、より適切な実行計画がオプティマイザで作成できます。
動的サンプリングを使用すると、次の作業が可能になります。
収集された統計が使用できない、あるいは見積りで重大なエラーを引き起こす可能性がある場合に、単一表の述語の選択性を見積ります。
表、および統計のない関連索引に対する統計を見積ります。
表、および統計が古すぎるために信頼できない関連索引に対する統計を見積ります。
この動的サンプリング機能は、OPTIMIZER_DYNAMIC_SAMPLING
パラメータにより制御されます。動的サンプリングにより必要な統計を自動的に収集するには、このパラメータを2以上の値に設定する必要があります。デフォルト値は2です。設定できるサンプリング・レベルの詳細は、「動的サンプリング・レベル」を参照してください。
重要なパフォーマンス属性は、コンパイル時に決定されます。Oracleでは、問合せで動的サンプリングを使用する利点があるかどうか、コンパイル時に判別されます。利点がある場合、再帰的SQL文が発行されて表のブロックの小さなランダム・サンプルがスキャンされ、関連する単一表の述語を適用することで述語の選択性の見積りが行われます。サンプルしたカーディナリティが、表のカーディナリティの見積りに使用される場合もあります。関連する列統計情報と索引統計情報も収集されます。
OPTIMIZER_DYNAMIC_SAMPLING
初期化パラメータの値によって、動的サンプリングの問合せで読み取られるブロック数が決定します。
関連項目: この初期化パラメータの詳細は、『Oracle Databaseリファレンス』を参照してください。 |
通常、迅速に(数秒以内で)完了する問合せに対しては、動的サンプリングのコストが発生するのは望ましくありません。しかし、次のいずれかの条件が当てはまる場合は、動的サンプリングが有効です。
動的サンプリングを使用すると、より優れた計画になる場合。
サンプリングにかかる時間が、問合せの実行時間全体のごく一部である場合。
問合せが何度も実行される場合。
動的サンプリングは、単一表の述語によるサブセットに適用したり、動的サンプリングが行われていない述語の通常の選択性の見積りと組み合せることができます。
動的サンプリングは、OPTIMIZER_DYNAMIC_SAMPLING
パラメータを使用して制御します。このパラメータの値は、0
〜10
に設定できます。デフォルトは2
です。
値が0
の場合、動的サンプリングが行われません。
パラメータの値が大きくなるにつれて、サンプリングされる表(分析された表、あるいは分析されていない表)のタイプについても、サンプリングで使用されるI/Oの量に関しても、動的サンプリングがより積極的に適用されるようになります。
動的サンプリングは、サンプリング対象の表内で行が挿入、削除または更新されていない場合、同じものが繰り返し使用されます。OPTIMIZER_FEATURES_ENABLE
パラメータが9.2.0より前のリリースに設定されている場合、動的サンプリングはオフになります。
サンプリング・レベルは、使用された動的サンプリング・レベルがカーソル・ヒントまたは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言語リファレンス』を参照してください。 |
Oracleでは、統計が欠落している表が検出されると、オプティマイザに必要な統計が動的に収集されます。ただし、ある種の表の場合、動的サンプリングは実行されません。これには、リモート表と外部表が含まれます。これらの場合および動的サンプリングが無効になっている場合、オプティマイザは統計にデフォルト値を使用します。表13-7および表13-8を参照してください。
この項では、次の内容を説明します。
表、索引および列の統計は、データ・ディクショナリに格納されます。データ・ディクショナリ内の統計を表示するには、適切なデータ・ディクショナリ・ビューを問い合せます(USER
、ALL
または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リファレンス』を参照してください。 |
列統計情報はヒストグラムとして格納できます。これらのヒストグラムは、列データの配分の正確な見積りを提供します。ヒストグラムによって、データが偏っている場合の選択性の見積りの精度が改善され、均一でないデータ配分が存在する最適な実行計画が得られます。
Oracleでは、列統計に次のタイプのヒストグラムを使用します。
ヒストグラムのタイプは、*TAB_COL_STATISTICS
ビュー(USER
およびDBA
)のHISTOGRAM
列に格納されます。この列の値は、HEIGHT BALANCED
、FREQUENCY
またはNONE
です。
高さ調整済ヒストグラムでは、列値が帯域に分割され、各帯域にほぼ同数の行が存在するようになっています。したがって、ヒストグラムによって提示される有用な情報が存在するのは、値範囲のエンドポイントが位置するところです。
値が1〜100の間に存在し、ヒストグラムが10バケットである列Cについて検討します。Cのデータ配分が均一な場合のヒストグラムは、図13-1のようになります。数字はエンドポイントの値です。
各バケット内の行数は、表内の全行数の10分の1です。均一に分布しているこの例では、4/10の行の値が、60〜100の間にあります。
データ配分が均一でない場合のヒストグラムは、図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つのバケットに対応します。
頻度ヒストグラムでは、列の値がそれぞれヒストグラムの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