| Oracle Database パフォーマンス・チューニング・ガイド 10gリリース2(10.2) B19207-02 |
|
この章では、プラン・スタビリティを使用してパフォーマンス特性を保持する方法を説明します。プラン・スタビリティは、新規のOracleリリースへアップグレードする際に、ルールベース・オプティマイザから問合せオプティマイザへ移行するときにも役立ちます。
この章には次の項があります。
プラン・スタビリティを使用すると、データベース環境を変更してもアプリケーションのパフォーマンス特性に影響が及ぶのを防ぐことができます。このような変更には、オプティマイザ統計の変更、オプティマイザ・モード設定の変更およびSORT_AREA_SIZEやBITMAP_MERGE_AREA_SIZEなどのメモリー構造のサイズに影響するパラメータの変更があります。プラン・スタビリティは、アプリケーションでパフォーマンスが変化してしまうリスクを冒すことができない場合に特に役立ちます。
プラン・スタビリティは、実行計画をストアド・アウトラインに保持します。アウトラインは、SQL文に関連付けられたオプティマイザ・ヒントのセットとして実装されます。文に対してアウトラインを使用できる場合、Oracleではストアド・ヒントが自動的に考慮され、これらのヒントに従って実行計画の生成が試行されます。
Oracleでは、1つまたはすべてのSQL文についてパブリックまたはプライベート・ストアド・アウトラインを作成できます。ストアド・アウトラインを使用可能にすると、オプティマイザはアウトラインから同じ実行計画を生成します。アウトラインをグループ化してカテゴリに分け、Oracleが使用するカテゴリを制御することによって、アウトラインの管理と配置を単純化できます。
Oracleがストアド・アウトラインに保持する計画は、システム構成または統計の変更にかかわらず一貫しています。また、ストアド・アウトラインを使用すると、以降のOracleリリースでオプティマイザが変更されても、生成した実行計画の安定性は保たれます。
Oracleではヒントを使用してストアド・プランを記録するため、プラン・スタビリティが実行計画を制御する度合いは、Oracleのヒント・メカニズムが実行計画を制御する度合いによって決定します。
SQLテキストは、そのストアド・アウトラインと1対1で対応しています。異なるリテラルを述語に指定すると、異なるアウトラインが適用されます。これを避けるには、アプリケーションのリテラルをバインド変数に置き換えてください。
|
関連項目:
リテラルをシステム生成のバインド変数に置き換えて、SQLを共有するように類似文を設定できます。これは、 |
プラン・スタビリティは、パフォーマンスに問題がない場合、実行計画の保持に依存します。しかし、多くの環境では、日付やオーダー番号などのデータ・タイプの属性はすぐに変わる可能性があります。そのような場合に実行計画を永続的に使用すると、データ特性の変更につれて、パフォーマンスが低下していく結果となります。
つまり、動的な環境では、計画の保持に依存するという技法は、問合せの最適化の目的に反することになります。問合せの最適化では、データの状態を正確に反映した統計に基づいて実行計画の生成が試みられます。したがって、プラン・スタビリティを制御する必要性と、データ特性の変更への適合性を持つオプティマイザの利点とのバランスを考慮する必要があります。
アウトラインは主に、特定のSQL文の実行計画生成に対するオプティマイザの結果に相当するヒントのセットからなります。Oracleによってアウトラインが作成されると、プラン・スタビリティは実行計画の生成に使用したのと同じデータを使用して最適化の結果を調べます。つまり、Oracleは実行計画そのものではなく実行計画への入力を使用して、アウトラインを生成します。
アウトライン・データは、OL$、OL$HINTSおよびOL$NODESの各表に格納します。アウトラインは、削除しなければ無期限に保持されます。
実行計画がキャッシュ内に存在しているかどうかの識別には、SQLテキストのみでなくアウトラインのカテゴリ名が使用されます。アウトラインが実行計画のキャッシュに及ぼす影響はこの点に限定されています。これにより、別のカテゴリの下でコンパイルしたSQL文を実行するときに、Oracleが、それとは別のあるカテゴリの下でコンパイルした実行計画を使用することはありません。
アウトラインを適切に機能させるためには、接尾辞_ENABLEDで終わるパラメータをはじめとするいくつかのパラメータ設定が、実行環境全体で一貫したものになっている必要があります。該当するパラメータは次のとおりです。
DBMS_OUTLNおよびDBMS_OUTLN_EDITパッケージによって、ストアド・アウトラインとそのアウトライン・カテゴリの管理に使用するプロシージャが提供されます。
ユーザーはDBMS_OUTLNを実行するためにEXECUTE_CATALOG_ROLEロールを必要としますが、パブリックにはDBMS_OUTLN_EDITに対する実行権限があります。DBMS_OUTLN_EDITパッケージは、実行者権限のパッケージです。
便利なDBMS_OUTLNおよびDBMS_OUTLN_EDITプロシージャのいくつかを次に示します。
CLEAR_USED: 指定されたアウトラインを消去します。
DROP_BY_CAT: 指定されたカテゴリに属するアウトラインを削除します。
UPDATE_BY_CAT: 指定されたカテゴリのアウトラインのカテゴリを新規の指定カテゴリに変更します。
EXACT_TEXT_SIGNATURES: テキストが完全一致するスキームに従って、アウトライン・シグネチャを計算します。
GENERATE_SIGNATURE: 指定されたSQLテキストのシグネチャを生成します。すべてのSQL文に対して自動的にアウトラインを作成することも、特定のSQL文に対して自分でアウトラインを作成することもできます。そのどちらの場合においても、アウトラインの入力はオプティマイザから導出されます。
初期化パラメータCREATE_STORED_OUTLINESをTRUEに設定すると、ストアド・アウトラインはOracleによって自動的に作成されます。パラメータを有効にすると、OracleはコンパイルされたSQL文すべてにアウトラインを作成します。CREATE OUTLINE文を使用して、特定の文に対するストアド・アウトラインを作成することもできます。
プライベート・アウトラインを作成または編集する場合、アウトライン・データはSYSTEMスキーマのグローバル一時表に書き込まれます。これらの表は、OL$、OL$HINTSおよびOL$NODESの各シノニムによりアクセスできます。
|
関連項目:
|
管理タスクを単純にするために、アウトラインをカテゴリに分類できます。CREATE OUTLINE文を使用すると、カテゴリを指定できます。指定されていなければ、DEFAULTカテゴリが選択されます。同様に、CREATE_STORED_OUTLINES初期化パラメータでカテゴリの名前を指定できますが、このパラメータにtrueを指定するとDEFAULTカテゴリ内にアウトラインを作成できます。
CREATE_STORED_OUTLINES初期化パラメータを使用してカテゴリ名を指定すると、その後で作成されるアウトラインはすべてOracleによってそのカテゴリに割り当てられます。この割当ては、そのカテゴリ名がリセットされるまで変更されません。アウトラインの生成を中断するには、このパラメータをfalseに設定します。
CREATE_STORED_OUTLINESをtrueに設定するか、またはカテゴリ名を使用しないCREATE OUTLINE文を使用した場合は、OracleはアウトラインをDEFAULTのカテゴリ名に割り当てます。
ストアド・アウトラインの使用をアクティブにした場合、Oracleは常に問合せオプティマイザを使用します。これは、アウトラインがヒントに依存し、そのヒントのほとんどが効率性のために問合せオプティマイザを必要とするからです。
OracleがSQL文をコンパイルする際にストアド・アウトラインを使用するには、システム・パラメータUSE_STORED_OUTLINESをtrueまたはカテゴリ名に設定します。USE_STORED_OUTLINESをtrueに設定すると、Oracleはアウトラインをdefaultカテゴリで使用します。USE_STORED_OUTLINESパラメータを使用してカテゴリを指定すると、USE_STORED_OUTLINESパラメータを別のカテゴリ名に再設定するか、USE_STORED_OUTLINESをfalseに設定してアウトラインの使用を中断するまで、Oracleはそのカテゴリでアウトラインを使用します。カテゴリ名を指定しているときにそのカテゴリ内にSQL文と一致するアウトラインが見つからない場合、Oracleはdefaultカテゴリ内のアウトラインを検索します。
カテゴリ内のすべてのアウトラインではなく特定のアウトラインを使用する場合、ALTER OUTLINE文を使用して特定のアウトラインを使用可能にします。特定のアウトラインを除くカテゴリ内のアウトラインを使用する場合、ALTER OUTLINE文を使用して、使用されているカテゴリ内の特定のアウトラインを使用禁止にします。ALTER OUTLINE文により、ストアド・アウトラインの名前の変更、別のカテゴリへの再割当てまたは再生成も可能です。
指定されたアウトラインは、アウトラインを持つSQL文のコンパイルのみを制御します。USE_STORED_OUTLINESをfalseに設定すると、Oracleはアウトラインを使用しません。USE_STORED_OUTLINESをfalseに設定し、CREATE_STORED_OUTLINESをtrueに設定した場合、Oracleはアウトラインを作成しますが、使用はしません。
USE_PRIVATE_OUTLINESパラメータを使用すると、プライベート・アウトラインの使用を制御できます。プライベート・アウトラインは、現行のセッション内のみで見られるアウトラインで、そのデータは現行の解析スキーマ内に常駐します。このアウトラインに対して行った変更はシステム上の他のセッションからは見られず、文のコンパイルへの適用は、現行セッションでUSE_PRIVATE_OUTLINESパラメータを指定することによってのみ行えます。編集内容をパブリック領域に保存するように明示的に選択した場合のみ、他のユーザーにも編集内容が表示されます。
オプティマイザは通常、問合せに最適な計画を選択しますが、ユーザーが実行環境に関して理解している事柄と、オプティマイザが従う経験則的方法とが整合しない場合があります。アウトラインを直接編集することで、アプリケーションを変更しなくてもSQL問合せをチューニングできます。
USE_PRIVATE_OUTLINESパラメータを有効にし、アウトラインを使用するSQL文を発行すると、オプティマイザは、USE_STORED_OUTLINESを有効にした場合に使用されるパブリック領域ではなく、セッションのプライベート領域からアウトラインを取り出します。セッションのプライベート領域にアウトラインが存在しない場合、オプティマイザは、文のコンパイルにアウトラインを使用しません。
CREATE OUTLINE文はすべて、CREATE ANY OUTLINE権限が必要です。FROM句を指定する場合は、SELECT権限も必要です。この権限は、アウトラインを使用する文に関連するSQLテキストとヒント・テキストを表示する権限を持つユーザーのみに与える必要があります。このロールは、CREATE OUTLINE FROMコマンドに必要です。コマンドの発行者がアウトラインの所有者でもある場合は、このロールは不要です。
アウトラインがV$SQLで使用されているかどうかをテストできます。SQL文でOUTLINE_CATEGORY列の問合せを行います。アウトラインが適用されている場合は、そのアウトラインが属しているカテゴリが列に挿入されます。適用されていない場合は、NULLになります。OUTLINE_SID列は、この特定のカーソルがパブリック・アウトラインを使用しているか(値は0)、プライベート・アウトラインを使用しているか(そのアウトラインを使用しているセッションのSID)を知らせます。
たとえば、次のような場合があります。
SELECT OUTLINE_CATEGORY, OUTLINE_SID FROM V$SQL WHERE SQL_TEXT LIKE 'SELECT COUNT(*) FROM emp%';
次のビューから、データ・ディクショナリに格納されているアウトラインおよびそれに関連するヒント・データの情報にアクセスできます。
アウトライン・カテゴリがmycatであるUSER_OUTLINESビューからアウトライン情報を取得するには、次の構文を使用します。
SELECT NAME, SQL_TEXT FROM USER_OUTLINES WHERE CATEGORY='mycat';
その結果、カテゴリmycat内の全アウトラインの名前とテキストが表示されます。
アウトラインname1に対して生成されたすべてのヒントを表示するには、次の構文を使用します。
SELECT HINT FROM USER_OUTLINE_HINTS WHERE NAME='name1';
互換性、形式およびアウトラインが使用可能かどうかについて、_OUTLINESビューのフラグを確認できます。たとえば、アウトラインが使用可能かどうかを判断するには、USER_OUTLINESビューのENABLEDフィールドを確認します。
SELECT NAME, CATEGORY, ENABLED FROM USER_OUTLINES;
Oracleは、USER_OUTLINESビューとUSER_OUTLINE_HINTSビューを、それぞれOL$表とOL$HINTS表のデータに基づいて作成します。OUTLNと呼ばれるスキーマを使用して、SYSTEM表領域にこれらの表とOL$NODES表も作成します。アウトラインがSYSTEM表領域の領域を過剰に使用している場合は、アウトラインを移動できます。そのためには、次の手順を使用して別の表領域を作成し、そこにアウトライン表を移動します。
CREATE_STORED_OUTLINESパラメータがオンであり、かつ、実行中のアプリケーションに多数のリテラルSQL文がある場合、デフォルトのシステム表領域すべてが使用される可能性があります。その場合は、DBMS_OUTLN.DROP_UNUSEDプロシージャを使用して、これらのリテラルSQLアウトラインを削除します。
OL$、OL$HINTSおよびOL$NODESの各表をエクスポートします。
EXP OUTLN/outln_password FILE = exp_file TABLES = 'OL$' 'OL$HINTS' 'OL$NODES'
CONNECT OUTLN/outln_password;
OL$表、OL$HINTS表およびOL$NODES表を削除します。
DROP TABLE OL$; DROP TABLE OL$HINTS; DROP TABLE OL$NODES;
CONNECT SYSTEM/system_password; CREATE TABLESPACE outln_ts DATAFILE 'tspace.dat' SIZE 2M DEFAULT STORAGE (INITIAL 10K NEXT 20K MINEXTENTS 1 MAXEXTENTS 999 PCTINCREASE 10) ONLINE;
ALTER USER OUTLN DEFAULT TABLESPACE outln_ts;
OUTLN_TS表領域に強制的にインポートするには、OUTLNユーザーについて、SYSTEM表領域の割当て制限を0KBに設定します。また、UNLIMITED TABLESPACE権限、およびRESOURCEロールなどの、無制限の表領域権限または割当て制限を持つすべてのロールを取り消す必要があります。OUTLN表領域の割当て制限を設定します。
OL$表、OL$HINTS表およびOL$NODES表をインポートします。
IMP OUTLN/outln_password FILE = exp_file TABLES = (OL$, OL$HINTS, OL$NODES)
インポート・プロセスが完了すると、OUTLNという名前のスキーマにOL$表、OL$HINTS表およびOL$NODES表が再作成され、OUTLN_TSという新しい表領域に配置されます。
このプロセスが完了した後、前のステップで削除された権限およびロールを追加することで、OUTLNユーザーの表領域割当て制限を適切に調整できます。
この項では、問合せオプティマイザの機能を利用してパフォーマンスを大幅に改善する手順を説明します。プラン・スタビリティは、システムが目標としている、パフォーマンスのよい実行計画を保ちながら、一方で、残りのSQL文に対する問合せオプティマイザの新機能の利点も利用する手段を提供します。
元の実行計画の正確な再現が保証されないSQL文および機能のクラスもありますが、プラン・スタビリティは移行プロセスにおける非常に便利な要素です。移行前に、アプリケーションのSQL文のすべてまたは大部分が取得されるまで、実行計画のアウトライン取得をオンにする必要があります。移行後に、特定のSQL文でパフォーマンスの問題がある場合は、以前の動作を元に戻す方法として、この文に対するストアド・アウトラインの使用をオンにできます。ストアド・アウトラインの使用は、変化するデータ・プロパティに計画が適応できないため、移行関連のパフォーマンスの問題を解決する最善の方法ではない場合がありますが、こうした問題への対処に使用できる数あるテクニックの1つです。
この項で説明する項目は次のとおりです。
ルールベース・オプティマイザを使用して開発したアプリケーションの場合、パフォーマンスを最適化するためにSQL文の手動チューニングに多大な作業量を投入している場合があります。プラン・スタビリティを使用すると、ルールベースの最適化から問合せの最適化へアップグレードする際にアプリケーションの動作を保持することによって、すでにパフォーマンス・チューニングに投入した作業を生かすことができます。
問合せの最適化に切り替える前にアプリケーションのアウトラインを作成すると、ルールベース・オプティマイザで生成した計画を使用しながら、切替え後に新しく作成されたアプリケーションで生成した文で問合せの計画を使用できます。アプリケーションのアウトラインを作成および使用するには、次のプロセスを実行します。
CREATE ANY OUTLINE権限があることを確認します。たとえば、SYSからは次のようになります。
GRANT CREATE ANY OUTLINE TO user-name
RBOCATアウトライン・カテゴリを指定します。
ALTER SESSION SET CREATE_STORED_OUTLINES = rbocat;
ALTER SESSION SET CREATE_STORED_OUTLINES = FALSE;
DBMS_STATSパッケージを使用して統計を収集します。
OPTIMIZER_MODEをCHOOSEに変更します。
RBOCATのアウトラインを使用するようにします。
ALTER SESSION SET USE_STORED_OUTLINES = rbocat;
プラン・スタビリティの制約上の理由から、このアプリケーションのSQL文のアクセス・パスは変更しないようにしてください。
問合せの最適化を使用していて、新しいOracleリリースにアップグレードする場合は、オプティマイザの変更に伴って変更された実行計画がいくつかのSQL文に存在する可能性が常にあります。このような変更によりパフォーマンスが向上しますが、アプリケーションによっては、パフォーマンスがすでに十分であるため、動作の変更は不要なリスクと考える場合もあります。このようなアプリケーションに対しては、次の手順により、アップグレード前にアウトラインを作成します。
ALTER SESSION SET CREATE_STORED_OUTLINES = ALL_QUERIES;
ALTER SESSION SET CREATE_STORED_OUTLINES = FALSE;
アップグレード後は、ストアド・アウトラインを使用可能にすることもできますし、あるいは、アップグレード後にパフォーマンスの低下を示す文があれば格納されていたアウトラインをバックアップとして使用することもできます。
バックアップとして使用する場合は、次のようにして、問題のある文にストアド・アウトラインを使用できます。
CATEGORYを次のようなカテゴリ名に変更します。
ALTER OUTLINE outline_name CHANGE CATEGORY TO problemcat;
problemcatのアウトラインを使用するようにします。
ALTER SESSION SET USE_STORED_OUTLINES = problemcat;
本番システムとは別に、テスト・システムを用意すれば、アップグレードとあわせてオプティマイザの動作を試すのに役立ちます。インポートとエクスポートを使用して、本番システムからテスト・システムへ統計を移行できます。それにより、テスト・システムの表をデータで満たす必要が少なくなります。
アウトラインはカテゴリごとにシステム間で移動できます。たとえば、problemcatカテゴリにアウトラインを作成した後、問合せベースのエクスポート・オプションを使用してカテゴリごとにエクスポートします。これは、ソース・データベース内のアウトラインをすべてエクスポートするのでなく、選択したアウトラインのみをあるデータベースから別のデータベースにエクスポートするうえで、便利で効率的な方法です。これを行うには、次の文を発行します。
EXP OUTLN/outln_password FILE=exp-file TABLES= 'OL$' 'OL$HINTS' 'OL$NODES' QUERY='WHERE CATEGORY="problemcat"'
|
![]() Copyright © 2000, 2008, Oracle Corporation. All Rights Reserved. |
|