ヘッダーをスキップ

Oracle Database パフォーマンス・チューニング・ガイド
10gリリース2(10.2)

B19207-02
目次
目次
索引
索引

戻る 次へ

18 プラン・スタビリティの使用方法

この章では、プラン・スタビリティを使用してパフォーマンス特性を保持する方法を説明します。プラン・スタビリティは、新規のOracleリリースへアップグレードする際に、ルールベース・オプティマイザから問合せオプティマイザへ移行するときにも役立ちます。

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

実行計画を保持するためのプラン・スタビリティの使用

プラン・スタビリティを使用すると、データベース環境を変更してもアプリケーションのパフォーマンス特性に影響が及ぶのを防ぐことができます。このような変更には、オプティマイザ統計の変更、オプティマイザ・モード設定の変更およびSORT_AREA_SIZEBITMAP_MERGE_AREA_SIZEなどのメモリー構造のサイズに影響するパラメータの変更があります。プラン・スタビリティは、アプリケーションでパフォーマンスが変化してしまうリスクを冒すことができない場合に特に役立ちます。

プラン・スタビリティは、実行計画をストアド・アウトラインに保持します。アウトラインは、SQL文に関連付けられたオプティマイザ・ヒントのセットとして実装されます。文に対してアウトラインを使用できる場合、Oracleではストアド・ヒントが自動的に考慮され、これらのヒントに従って実行計画の生成が試行されます。

Oracleでは、1つまたはすべてのSQL文についてパブリックまたはプライベート・ストアド・アウトラインを作成できます。ストアド・アウトラインを使用可能にすると、オプティマイザはアウトラインから同じ実行計画を生成します。アウトラインをグループ化してカテゴリに分け、Oracleが使用するカテゴリを制御することによって、アウトラインの管理と配置を単純化できます。

Oracleがストアド・アウトラインに保持する計画は、システム構成または統計の変更にかかわらず一貫しています。また、ストアド・アウトラインを使用すると、以降のOracleリリースでオプティマイザが変更されても、生成した実行計画の安定性は保たれます。


注意:

市場を通じて多量に販売するアプリケーションを開発する場合は、ストアド・アウトラインを使用すると、すべての顧客が確実に同じ実行計画にアクセスするようにできます。 


プラン・スタビリティでのヒントの使用

Oracleではヒントを使用してストアド・プランを記録するため、プラン・スタビリティが実行計画を制御する度合いは、Oracleのヒント・メカニズムが実行計画を制御する度合いによって決定します。

SQLテキストは、そのストアド・アウトラインと1対1で対応しています。異なるリテラルを述語に指定すると、異なるアウトラインが適用されます。これを避けるには、アプリケーションのリテラルをバインド変数に置き換えてください。

関連項目:

リテラルをシステム生成のバインド変数に置き換えて、SQLを共有するように類似文を設定できます。これは、CREATE OUTLINE文でなくCREATE_STORED_OUTLINESパラメータを使用してアウトラインが生成されている場合のプラン・スタビリティにかぎり有効です。また、アウトラインはCURSOR_SHARINGパラメータをSIMILARに設定して作成してあり、アウトラインを使用するときにも、このパラメータをSIMILARに設定する必要があります。詳細は、第7章「メモリーの構成と使用方法」を参照してください。  

プラン・スタビリティは、パフォーマンスに問題がない場合、実行計画の保持に依存します。しかし、多くの環境では、日付オーダー番号などのデータ・タイプの属性はすぐに変わる可能性があります。そのような場合に実行計画を永続的に使用すると、データ特性の変更につれて、パフォーマンスが低下していく結果となります。

つまり、動的な環境では、計画の保持に依存するという技法は、問合せの最適化の目的に反することになります。問合せの最適化では、データの状態を正確に反映した統計に基づいて実行計画の生成が試みられます。したがって、プラン・スタビリティを制御する必要性と、データ特性の変更への適合性を持つオプティマイザの利点とのバランスを考慮する必要があります。

アウトラインでのヒントの使用方法

アウトラインは主に、特定のSQL文の実行計画生成に対するオプティマイザの結果に相当するヒントのセットからなります。Oracleによってアウトラインが作成されると、プラン・スタビリティは実行計画の生成に使用したのと同じデータを使用して最適化の結果を調べます。つまり、Oracleは実行計画そのものではなく実行計画への入力を使用して、アウトラインを生成します。


注意:

Oracleは、SYS表領域にUSER_OUTLINESビューとUSER_OUTLINE_HINTSビューを、それぞれOL$表とOL$HINTS表のデータに基づいて作成します。OL$OL$HINTSおよびOL$NODES表の直接操作は禁止されています。

SQL文にヒントを組み込むことはできますが、その結果がOracleによるアウトラインの使用方法に影響することはありません。Oracleは、ヒントを使用して修正されたSQL文を、アウトラインに格納されている元のSQL文とは異なるものとして認識します。  


アウトラインの格納

アウトライン・データは、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プロシージャのいくつかを次に示します。

アウトラインの作成

すべてのSQL文に対して自動的にアウトラインを作成することも、特定のSQL文に対して自分でアウトラインを作成することもできます。そのどちらの場合においても、アウトラインの入力はオプティマイザから導出されます。

初期化パラメータCREATE_STORED_OUTLINESTRUEに設定すると、ストアド・アウトラインはOracleによって自動的に作成されます。パラメータを有効にすると、OracleはコンパイルされたSQL文すべてにアウトラインを作成します。CREATE OUTLINE文を使用して、特定の文に対するストアド・アウトラインを作成することもできます。

プライベート・アウトラインを作成または編集する場合、アウトライン・データはSYSTEMスキーマのグローバル一時表に書き込まれます。これらの表は、OL$OL$HINTSおよびOL$NODESの各シノニムによりアクセスできます。


注意:

アウトラインを作成するスキーマにCREATE ANY OUTLINE権限があることを必ず確認してください。この権限が存在しない場合は、CREATE_STORED_OUTLINE初期化パラメータをオンにしても、アプリケーションの実行後にデータベース内でアウトラインを見つけることはできません。

また、CREATE_STORED_OUTLINES初期化パラメータが有効で、実行中のアプリケーションに多数のリテラルSQL文がある場合、デフォルトのシステム表領域がすべて使用される可能性があります。その場合は、DBMS_OUTLN.DROP_UNUSEDプロシージャを使用して、これらのリテラルSQLのアウトラインを削除します。 


関連項目:

  • CREATE OUTLINE文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。

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

  • ルールベース・オプティマイザから問合せオプティマイザに移行する方法の詳細は、「RBOから問合せオプティマイザへの移行」を参照してください。

 

ストアド・アウトラインにカテゴリ名を使用する方法

管理タスクを単純にするために、アウトラインをカテゴリに分類できます。CREATE OUTLINE文を使用すると、カテゴリを指定できます。指定されていなければ、DEFAULTカテゴリが選択されます。同様に、CREATE_STORED_OUTLINES初期化パラメータでカテゴリの名前を指定できますが、このパラメータにtrueを指定するとDEFAULTカテゴリ内にアウトラインを作成できます。

CREATE_STORED_OUTLINES初期化パラメータを使用してカテゴリ名を指定すると、その後で作成されるアウトラインはすべてOracleによってそのカテゴリに割り当てられます。この割当ては、そのカテゴリ名がリセットされるまで変更されません。アウトラインの生成を中断するには、このパラメータをfalseに設定します。

CREATE_STORED_OUTLINEStrueに設定するか、またはカテゴリ名を使用しないCREATE OUTLINE文を使用した場合は、OracleはアウトラインをDEFAULTのカテゴリ名に割り当てます。

ストアド・アウトラインの使用

ストアド・アウトラインの使用をアクティブにした場合、Oracleは常に問合せオプティマイザを使用します。これは、アウトラインがヒントに依存し、そのヒントのほとんどが効率性のために問合せオプティマイザを必要とするからです。

OracleがSQL文をコンパイルする際にストアド・アウトラインを使用するには、システム・パラメータUSE_STORED_OUTLINEStrueまたはカテゴリ名に設定します。USE_STORED_OUTLINEStrueに設定すると、Oracleはアウトラインをdefaultカテゴリで使用します。USE_STORED_OUTLINESパラメータを使用してカテゴリを指定すると、USE_STORED_OUTLINESパラメータを別のカテゴリ名に再設定するか、USE_STORED_OUTLINESfalseに設定してアウトラインの使用を中断するまで、Oracleはそのカテゴリでアウトラインを使用します。カテゴリ名を指定しているときにそのカテゴリ内にSQL文と一致するアウトラインが見つからない場合、Oracleはdefaultカテゴリ内のアウトラインを検索します。

カテゴリ内のすべてのアウトラインではなく特定のアウトラインを使用する場合、ALTER OUTLINE文を使用して特定のアウトラインを使用可能にします。特定のアウトラインを除くカテゴリ内のアウトラインを使用する場合、ALTER OUTLINE文を使用して、使用されているカテゴリ内の特定のアウトラインを使用禁止にします。ALTER OUTLINE文により、ストアド・アウトラインの名前の変更、別のカテゴリへの再割当てまたは再生成も可能です。

関連項目:

ALTER OUTLINE文の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 

指定されたアウトラインは、アウトラインを持つSQL文のコンパイルのみを制御します。USE_STORED_OUTLINESfalseに設定すると、Oracleはアウトラインを使用しません。USE_STORED_OUTLINESfalseに設定し、CREATE_STORED_OUTLINEStrueに設定した場合、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コマンドに必要です。コマンドの発行者がアウトラインの所有者でもある場合は、このロールは不要です。


注意:

USE_STORED_OUTLINESおよびUSE_PRIVATE_OUTLINESパラメータは、システムまたはセッション固有です。これらは初期化パラメータではありません。 これらのパラメータの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 


アウトラインが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 Databaseリファレンス』を参照してください。 

アウトライン表の移動

Oracleは、USER_OUTLINESビューとUSER_OUTLINE_HINTSビューを、それぞれOL$表とOL$HINTS表のデータに基づいて作成します。OUTLNと呼ばれるスキーマを使用して、SYSTEM表領域にこれらの表とOL$NODES表も作成します。アウトラインがSYSTEM表領域の領域を過剰に使用している場合は、アウトラインを移動できます。そのためには、次の手順を使用して別の表領域を作成し、そこにアウトライン表を移動します。

  1. CREATE_STORED_OUTLINESパラメータがオンであり、かつ、実行中のアプリケーションに多数のリテラルSQL文がある場合、デフォルトのシステム表領域すべてが使用される可能性があります。その場合は、DBMS_OUTLN.DROP_UNUSEDプロシージャを使用して、これらのリテラルSQLアウトラインを削除します。

  2. Oracle Export Utilityを使用して、OL$OL$HINTSおよびOL$NODESの各表をエクスポートします。

    EXP OUTLN/outln_password 
        FILE = exp_file TABLES = 'OL$' 'OL$HINTS' 'OL$NODES'
    
    
  3. SQL*Plusを起動し、データベースに接続します。

    CONNECT OUTLN/outln_password;
    
    
  4. 以前のOL$表、OL$HINTS表およびOL$NODES表を削除します。

    DROP TABLE OL$; 
    DROP TABLE OL$HINTS; 
    DROP TABLE OL$NODES; 
    
    
    
  5. 表に新しい表領域を作成します。

    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; 
    
    
  6. 次の文を入力して、デフォルトの表領域を変更します。

    ALTER USER OUTLN DEFAULT TABLESPACE outln_ts;
    
    
  7. OUTLN_TS表領域に強制的にインポートするには、OUTLNユーザーについて、SYSTEM表領域の割当て制限を0KBに設定します。また、UNLIMITED TABLESPACE権限、およびRESOURCEロールなどの、無制限の表領域権限または割当て制限を持つすべてのロールを取り消す必要があります。OUTLN表領域の割当て制限を設定します。

  8. 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ユーザーの表領域割当て制限を適切に調整できます。

関連項目:

  • ExportおよびImportのユーティリティの使用方法は、『Oracle Databaseユーティリティ』を参照してください。Importユーティリティの説明の箇所にある表領域の再編成に関する項に注意してください。

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

 

問合せオプティマイザのアップグレードによるプラン・スタビリティの使用

この項では、問合せオプティマイザの機能を利用してパフォーマンスを大幅に改善する手順を説明します。プラン・スタビリティは、システムが目標としている、パフォーマンスのよい実行計画を保ちながら、一方で、残りのSQL文に対する問合せオプティマイザの新機能の利点も利用する手段を提供します。

元の実行計画の正確な再現が保証されないSQL文および機能のクラスもありますが、プラン・スタビリティは移行プロセスにおける非常に便利な要素です。移行前に、アプリケーションのSQL文のすべてまたは大部分が取得されるまで、実行計画のアウトライン取得をオンにする必要があります。移行後に、特定のSQL文でパフォーマンスの問題がある場合は、以前の動作を元に戻す方法として、この文に対するストアド・アウトラインの使用をオンにできます。ストアド・アウトラインの使用は、変化するデータ・プロパティに計画が適応できないため、移行関連のパフォーマンスの問題を解決する最善の方法ではない場合がありますが、こうした問題への対処に使用できる数あるテクニックの1つです。

この項で説明する項目は次のとおりです。

RBOから問合せオプティマイザへの移行

ルールベース・オプティマイザを使用して開発したアプリケーションの場合、パフォーマンスを最適化するためにSQL文の手動チューニングに多大な作業量を投入している場合があります。プラン・スタビリティを使用すると、ルールベースの最適化から問合せの最適化へアップグレードする際にアプリケーションの動作を保持することによって、すでにパフォーマンス・チューニングに投入した作業を生かすことができます。

問合せの最適化に切り替える前にアプリケーションのアウトラインを作成すると、ルールベース・オプティマイザで生成した計画を使用しながら、切替え後に新しく作成されたアプリケーションで生成した文で問合せの計画を使用できます。アプリケーションのアウトラインを作成および使用するには、次のプロセスを実行します。


注意:

この手順をよく読んで、内容を十分理解してから実行してください。  


  1. アウトラインを作成するスキーマにCREATE ANY OUTLINE権限があることを確認します。たとえば、SYSからは次のようになります。

    GRANT CREATE ANY OUTLINE TO user-name 
    
    
    
  2. 次のような構文を実行してアウトライン・カテゴリを指定します。ここでは、例としてRBOCATアウトライン・カテゴリを指定します。

    ALTER SESSION SET CREATE_STORED_OUTLINES = rbocat;
    
    
  3. 重要なSQL文すべてにストアド・アウトラインを獲得できるよう十分に時間をとってアプリケーションを実行します。

  4. アウトライン生成を中断します。

    ALTER SESSION SET CREATE_STORED_OUTLINES = FALSE;
    
    
  5. DBMS_STATSパッケージを使用して統計を収集します。

  6. パラメータOPTIMIZER_MODECHOOSEに変更します。

  7. 次の構文を入力して、OracleがカテゴリRBOCATのアウトラインを使用するようにします。

    ALTER SESSION SET USE_STORED_OUTLINES = rbocat;
    
    
  8. アプリケーションを実行します。

    プラン・スタビリティの制約上の理由から、このアプリケーションのSQL文のアクセス・パスは変更しないようにしてください。


    注意:

    手順2で問合せが実行されなかった場合は、問合せの最適化に切り替えた後も、以前の問合せの動作が獲得される可能性があります。その場合は、オプティマイザ・モードをRULEに変更し、問合せのアウトラインを作成してから、オプティマイザ・モードを再びCHOOSEに戻します。  


問合せオプティマイザを使用している場合の新規Oracleリリースへの移行

問合せの最適化を使用していて、新しいOracleリリースにアップグレードする場合は、オプティマイザの変更に伴って変更された実行計画がいくつかのSQL文に存在する可能性が常にあります。このような変更によりパフォーマンスが向上しますが、アプリケーションによっては、パフォーマンスがすでに十分であるため、動作の変更は不要なリスクと考える場合もあります。このようなアプリケーションに対しては、次の手順により、アップグレード前にアウトラインを作成します。


注意:

この手順をよく読んで、内容を十分理解してから実行してください。  


  1. 次の構文を入力して、アウトラインを作成できるようにします。

    ALTER SESSION SET CREATE_STORED_OUTLINES = ALL_QUERIES;
    
    
  2. 重要なSQL文すべてにストアド・アウトラインを獲得できるよう十分に時間をとってアプリケーションを実行します。

  3. 次の構文を入力して、アウトラインの生成を中断します。

    ALTER SESSION SET CREATE_STORED_OUTLINES = FALSE;
    
    
  4. 新しいバージョンのRDBMSに本番システムをアップグレードします。

  5. アプリケーションを実行します。

アップグレード後は、ストアド・アウトラインを使用可能にすることもできますし、あるいは、アップグレード後にパフォーマンスの低下を示す文があれば格納されていたアウトラインをバックアップとして使用することもできます。

バックアップとして使用する場合は、次のようにして、問題のある文にストアド・アウトラインを使用できます。

  1. 問題のあるSQL文それぞれについて、関連するストアド・アウトラインのCATEGORYを次のようなカテゴリ名に変更します。

    ALTER OUTLINE outline_name CHANGE CATEGORY TO problemcat;
    
    
  2. 次の構文を入力して、Oracleがカテゴリ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"' 

戻る 次へ
Oracle
Copyright © 2000, 2008, Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引