ヘッダーをスキップ

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

B19207-02
目次
目次
索引
索引

戻る 次へ

17 SQLアクセス・アドバイザ

この章では、SQLアクセス・アドバイザの使用方法について説明します。SQLアクセス・アドバイザは、マテリアライズド・ビュー、索引およびマテリアライズド・ビュー・ログについてアドバイスを提供するチューニング・ツールです。この章には次の項があります。

DBMS_ADVISORパッケージのSQLアクセス・アドバイザの概要

データ集中型の複雑な問合せの実行時に最適なパフォーマンスを実現できるようにデータベースをチューニングする際、マテリアライズド・ビューと索引が必要になります。SQLアクセス・アドバイザでは、指定のワークロードに関するマテリアライズド・ビュー、マテリアライズド・ビュー・ログおよび索引の適切なセットが推奨されるため、パフォーマンスの目標を達成するのに役立ちます。SQLを最適化する際には、これらの構造を理解して使用することが重要です。これにより、データを取り出す際のパフォーマンスが大幅に向上します。ただし、このような利点を利用するにはそれなりの負担が伴います。これらのオブジェクトの作成やメンテナンスには時間がかかり、また領域要件も重要になります。

SQLアクセス・アドバイザでは、ビットマップ索引、ファンクション索引およびBツリー索引が推奨されています。ビットマップ索引を使用すると、多くのタイプの非定型問合せの応答時間が短縮され、その他の索引付けの方法と比べて記憶域要件が軽減されます。Bツリー索引は、一意またはほぼ一意のキーに索引を付ける方法で、データ・ウェアハウスで最も一般的に使用されています。

また、SQLアクセス・アドバイザの別のコンポーネントにより、マテリアライズド・ビューの最適化も推奨されています。これにより、マテリアライズド・ビューの高速リフレッシュが可能になり、汎用的なクエリー・リライトを利用できます。

SQLアクセス・アドバイザを実行するには、Oracle Enterprise Manager(「セントラル・アドバイザ」ページからアクセス可能)からSQLアクセス・アドバイザ・ウィザードを使用するか、DBMS_ADVISORパッケージを起動します。DBMS_ADVISORパッケージは、任意のPL/SQLプログラムからコール可能な分析およびアドバイザ用のファンクションおよびプロシージャの集合です。図17-1は、ユーザー定義の表またはSQLキャッシュから取得した特定のワークロードについてSQLアクセス・アドバイザがマテリアライズド・ビューを推奨する方法を示します。ワークロードが提供されていない場合、SQLアクセス・アドバイザは仮想ワークロードも生成および使用できます。

図 17-1    マテリアライズド・ビューとSQLアクセス・アドバイザ


画像の説明

SQLアクセス・アドバイザ・ウィザードまたはAPIを使用して、次の操作を実行できます。

また、SQLアクセス・アドバイザのAPIを使用して、次の操作を実行できます。

表と索引のカーディナリティ、およびディメンション・レベルのすべての列、JOIN KEY列およびファクト表のキー列の個別カーディナリティに関する構造的な統計を収集すると、SQLアクセス・アドバイザの推奨事項は大幅に向上します。これを行うには、DBMS_STATSパッケージを使用して正確な統計または見積り統計を収集します。統計の収集は時間のかかる処理であり、極端な統計精度は必要ないため、通常は統計を見積もることをお薦めします。これらの統計がない場合、その表を参照する問合せはワークロードで無効とマークされるため、これらの問合せについては推奨事項が生成されなくなります。また、既存のすべての索引とマテリアライズド・ビューを分析しておくこともお薦めします。DBMS_STATSパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

SQLアクセス・アドバイザの使用方法の概要

SQLアクセス・アドバイザを使用する最も簡単な方法は、ウィザードを起動する方法です。このウィザードは、Oracle Enterprise Managerの「セントラル・アドバイザ」ページからアクセスできます。DBMS_ADVISORパッケージを介してSQLアクセス・アドバイザを使用する方が望ましい場合は、この項の説明にある基本的なコンポーネントや、様々なプロシージャをコールする必要があるシーケンスについて参照してください。

この項では、一連の推奨事項を生成するための4つの手順について説明します。

手順 1    タスクの作成

推奨を行う前に、タスクを作成する必要があります。推奨プロセスの結果など、推奨プロセスに関するすべての情報はタスク内に格納されるため、タスクは重要です。Oracle Enterprise ManagerのウィザードまたはDBMS_ADVISOR.QUICK_TUNEプロシージャを使用する場合、タスクは自動的に作成されます。これ以外のすべてのケースにおいては、DBMS_ADVISOR.CREATE_TASKプロシージャを使用してタスクを作成する必要があります。

タスクの処理内容を制御するには、DBMS_ADVISOR.SET_TASK_PARAMETERプロシージャを使用してタスクのパラメータを定義します。

タスクの作成の詳細は、「タスクの作成」を参照してください。

手順 2    ワークロードの定義

ワークロードは、SQLアクセス・アドバイザの主な入力データであり、1つ以上のSQL文と、各文を完全に説明する様々な統計や属性で構成されています。ワークロードにターゲットのビジネス・アプリケーションのすべてのSQL文が含まれる場合、このワークロードは全ワークロードとみなされます。一方、ワークロードにSQL文のサブセットが含まれる場合、このワークロードは部分ワークロードと呼ばれます。全ワークロードと部分ワークロードの違いは、全ワークロードの場合、効率的に使用されていない既存のマテリアライズド・ビューや索引を検出すると、SQLアクセス・アドバイザがこれらを削除するよう推奨する点にあります。

通常、SQLアクセス・アドバイザでは、すべての分析アクティビティの基礎としてワークロードを使用します。ワークロードには様々な種類の文が含まれることがありますが、ワークロードでは、特定の統計、ビジネスの重要性、または統計とビジネスの重要性の組合せに応じてエントリにランクが付けられます。このランクは重要です。このようにランクを付けることにより、SQLアクセス・アドバイザはビジネスへの影響が少ないSQL文よりも最も重要なSQL文を先に処理できるようになるためです。

データの集合を有効なワークロードとみなすために、SQLアクセス・アドバイザには特定の属性が必要になることがあります。一部の項目が欠落していても分析は実行できますが、推奨事項の品質が大幅に低下する場合があります。たとえば、SQLアクセス・アドバイザでは、SQL問合せとこの問合せを実行したユーザーがワークロードに含まれている必要があります。その他すべての属性はオプションです。ただし、ワークロードにI/OおよびCPU情報も含まれていると、SQLアクセス・アドバイザでは文の現在の効率をより正確に評価できる場合があります。ワークロードは、DBMS_ADVISOR.CREATE_SQLWKLDプロシージャを使用して作成される別のオブジェクトとして格納され、多くのアドバイザ・タスク間で簡単に共有できます。ワークロードは独立しているため、DBMS_ADVISOR.ADD_SQLWKLD_REFプロシージャを使用してタスクにリンクする必要があります。いったんこのリンクが確立されると、すべてのアドバイザ・タスクからワークロードに対する依存性が削除されるまではワークロードを削除または変更できなくなります。ワークロード参照が削除されるのは、親アドバイザ・タスクが削除される場合か、ユーザーがDBMS_ADVISOR.DELETE_SQLWKLD_REFプロシージャを使用してアドバイザ・タスクからワークロード参照を手動で削除する場合です。

SQLアクセス・アドバイザはワークロードなしでも使用できますが、最良の結果を得るには、ユーザー指定の表またはSQLチューニング・セットの形式でワークロードを提供するか、SQLキャッシュからワークロードをインポートする必要があります。ワークロードが提供されない場合、SQLアクセス・アドバイザは、スキーマに定義されているディメンションに基づいて仮想ワークロードを生成および使用できます。

ワークロードがリポジトリにロードされるか、推奨事項が生成されると、ワークロードにフィルタを適用し、分析対象を制限できます。これにより、様々なワークロード・シナリオに基づいて一連の各種推奨事項を生成できるようになります。

ワークロードの推奨プロセスとカスタマイズは、SQLアクセス・アドバイザ・パラメータによって制御されます。これらのパラメータは、必要な推奨事項のタイプや推奨内容のネーミング規則など、推奨プロセスの様々な側面を制御します。ワークロードに関しては、パラメータは、ワークロードの存続時間やワークロードに適用するフィルタを制御します。

これらのパラメータを設定するには、SET_TASK_PARAMETERおよびSET_SQLWKLD_PARAMETERプロシージャを使用します。パラメータは、タスクまたはワークロード・オブジェクトの存続期間は設定されたままであるという点において永続的です。SET_TASK_PARAMETERプロシージャを使用してパラメータを設定した場合、SET_TASK_PARAMETERをもう1回コールするまではこのパラメータは変更されません。

ワークロードの詳細は、「ワークロードの内容の定義」を参照してください。

手順 3    推奨事項の生成

タスクが存在するときにこのタスクにワークロードをリンクし、適切なパラメータを設定すると、DBMS_ADVISOR.EXECUTE_TASKプロシージャを使用して推奨事項を生成できます。これらの推奨事項は、SQLアクセス・アドバイザ・リポジトリに格納されます。

推奨プロセスにより、多数の推奨事項が生成されます。各推奨事項には、1つ以上のアクションが含まれます。たとえば、マテリアライズド・ビューを作成し、これを分析して統計情報を収集します。

タスクの推奨事項には、単純な提案から、索引、マテリアライズド・ビューおよびマテリアライズド・ビュー・ログなどの一連のデータベース・オブジェクトの実装を必要とする複雑なソリューションまで多岐にわたります。アドバイザ・タスクが実行されると、収集されたデータとユーザー調整のタスク・パラメータが慎重に分析されます。これにより、SQLアクセス・アドバイザでは、組み込まれているナレッジに基づいて精度を形成しようとします。次に、この精度は微調整され、ユーザーが表示および実装できるよう構造化された推奨事項の形式で格納されます。

推奨事項の生成の詳細は、「推奨事項の生成」を参照してください。

手順 4    推奨事項の表示と実装

SQLアクセス・アドバイザの推奨事項を表示する方法には2通りあります。カタログ・ビューを使用する方法と、DBMS_ADVISOR.GET_TASK_SCRIPTプロシージャを使用してスクリプトを生成する方法です。Enterprise Managerでは、SQLアクセス・アドバイザ・プロセスが完了すると推奨事項が表示されます。

推奨事項を表示するためにカタログ・ビューを使用する方法の詳細は、「推奨事項の表示」を参照してください。 スクリプトの作成方法の詳細は、「SQLスクリプトの生成」を参照してください。

すべての推奨事項を受け入れる必要はなく、推奨事項のスクリプトに含める推奨事項をマークできます。

最終手順では、推奨事項を実装し、問合せのパフォーマンスが向上したかどうかを検証します。

SQLアクセス・アドバイザ・リポジトリ

SQLアクセス・アドバイザによって生成されたすべての必要情報は、データベース・ディクショナリの一部であるアドバイザ・リポジトリに格納されます。リポジトリを使用する利点は、次のとおりです。

SQLアクセス・アドバイザの使用方法

この項では、SQLアクセス・アドバイザに関する一般的な情報や、SQLアクセス・アドバイザを使用するために必要な手順について説明します。この項には、次の項目があります。

SQLアクセス・アドバイザの使用手順

図17-2には、SQLアクセス・アドバイザの使用手順と、SQLアクセス・アドバイザのすべてのパラメータの概要、およびその適切な使用タイミングを示します。

図 17-2    SQLアクセス・アドバイザのフローチャート


画像の説明

SQLアクセス・アドバイザの使用に必要な権限

SQLアクセス・アドバイザを管理または使用するには、ADVISOR権限が必要です。SQLアクセス・アドバイザは、ワークロードの処理時に各文を検証し、表と列の参照関係を識別しようとします。この文のオリジナル・ユーザーが実行しているものとして各文を処理することによって検証されます。このユーザーが特定の表に対するSELECT権限を持っていない場合、SQLアクセス・アドバイザは、この表を参照している文をバイパスします。これにより、多くの文が分析から除外されることがあります。SQLアクセス・アドバイザがワークロード内のすべての文を除外すると、ワークロードは無効になり、次のメッセージが戻されます。

QSM-00774, there are no SQL statements to process for task TASK_NAME

重要なワークロード問合せが欠落しないようにするには、現在のデータベース・ユーザーが、マテリアライズド・ビューの分析対象の表に対するSELECT権限を持つ必要があります。これらの表については、ロールを介してこれらのSELECT権限を取得できません。

タスクとテンプレートの設定

この項では、タスクとテンプレートの設定に関する次の側面について説明します。

タスクの作成

アドバイザ・タスクとは、分析する内容と、この分析結果の提供先を定義するタスクです。ユーザーは、各タスクが特化した任意の数のタスクを作成できます。これらすべてのタスクは同じアドバイザ・タスク・モデルに基づいており、同じリポジトリを共有します。

タスクを作成するには、CREATE_TASKプロシージャを使用します。 構文は、次のとおりです。

DBMS_ADVISOR.CREATE_TASK (
   advisor_name          IN VARCHAR2,
   task_id               OUT NUMBER,
   task_name             IN OUT VARCHAR2,
   task_desc             IN VARCHAR2 := NULL,
   template              IN VARCHAR2 := NULL,
   is_template           IN VARCHAR2 := 'FALSE',
   how_created           IN VARCHAR2 := NULL);

DBMS_ADVISOR.CREATE_TASK (
   advisor_name          IN VARCHAR2,
   task_name             IN VARCHAR2,
   task_desc             IN VARCHAR2 := NULL,
   template              IN VARCHAR2 := NULL,
   is_template           IN VARCHAR2 := 'FALSE',
   how_created           IN VARCHAR2 := NULL); 

次に、このプロシージャの使用例を示します。

VARIABLE task_id NUMBER;
VARIABLE task_name VARCHAR2(255);
EXECUTE :task_name := 'MYTASK';
EXECUTE DBMS_ADVISOR.CREATE_TASK ('SQL Access Advisor', :task_id, :task_name);

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

テンプレートの使用方法

タスクまたはワークロードの理想的な構成が識別されると、将来のタスクとワークロードの基となるテンプレートとしてこの構成を保存できます。

これにより、将来のタスクを作成する場合の理にかなった開始ポイントまたはテンプレートとして使用可能なタスクまたはワークロードを、任意の数だけ設定できるようになります。テンプレートを設定することにより、チューニング分析の実行時間を短縮できます。また、チューニング分析をビジネス処理に合うようにカスタマイズすることもできます。

テンプレートからタスクを作成するには、新しいタスクの作成時に使用するテンプレートを指定します。このとき、SQLアクセス・アドバイザは、新しく作成されたタスクにテンプレートからデータおよびパラメータ設定をコピーします。また、既存のタスクをテンプレートとして設定するには、タスクの作成時にテンプレート属性を使用するか、後でUPDATE_TASK_ATTRIBUTEプロシージャを使用します。

タスクをテンプレートとして使用するには、新しいタスクの作成時にタスクを使用することをSQLアクセス・アドバイザに通知します。このとき、SQLアクセス・アドバイザは、新しく作成されたタスクにテンプレートのデータおよびパラメータ設定をコピーします。また、既存のタスクをテンプレートとして設定するには、テンプレート属性を設定します。この操作は、コマンドラインまたはEnterprise Managerで行います。

新しいワークロード・オブジェクトを作成するためのテンプレートとしてワークロード・オブジェクトを使用することもできます。タスクをテンプレートとして使用する場合と同じガイドラインに従うことにより、ワークロード・オブジェクトにも明確な開始ポイントを指定できます。タスク・テンプレートの場合と同様、テンプレートのワークロード・オブジェクトを使用して作成できるのは、同じワークロード・オブジェクトのみです。

テンプレートの作成

テンプレートの作成例は、次のとおりです。

  1. MY_TEMPLATEと呼ばれるテンプレートを作成します。

    VARIABLE template_id NUMBER;
    VARIABLE template_name VARCHAR2(255);
    EXECUTE :template_name := 'MY_TEMPLATE';
    EXECUTE DBMS_ADVISOR.CREATE_TASK('SQL Access Advisor',:template_id, -
                                     :template_name, is_template => 'TRUE');
    
    
  2. テンプレートのパラメータを設定します。たとえば、次の例では、推奨される索引とマテリアライズド・ビューのネーミング規則とデフォルトの表領域を設定します。

    -- set naming conventions for recommended indexes/mvs
    EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
       :template_name, 'INDEX_NAME_TEMPLATE', 'SH_IDX$$_<SEQ>');
    
    EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
       :template_name, 'MVIEW_NAME_TEMPLATE', 'SH_MV$$_<SEQ>');
    
    -- set default tablespace for recommended indexes/mvs
    EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
       :template_name, 'DEF_INDEX_TABLESPACE', 'SH_INDEXES');
    
    EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
       :template_name, 'DEF_MVIEW_TABLESPACE', 'SH_MVIEWS');
    
    
  3. これで、このテンプレートは、次のようにタスクを作成するときの開始ポイントとして使用できます。

    VARIABLE task_id NUMBER;
    VARIABLE task_name VARCHAR2(255);
    EXECUTE :task_name := 'MYTASK';
    EXECUTE DBMS_ADVISOR.CREATE_TASK('SQL Access Advisor', :task_id, -
                                     :task_name, template=>'MY_TEMPLATE');
    
    

    次の例では、事前定義済テンプレートSQLACCESS_WAREHOUSEを使用します。詳細は、表17-4を参照してください。

    EXECUTE DBMS_ADVISOR.CREATE_TASK('SQL Access Advisor', -
       :task_id, :task_name,  template=>'SQLACCESS_WAREHOUSE');
    

ワークロードの管理

この項では、ワークロードの管理に関する次の側面について説明します。

ワークロード・オブジェクト

ワークロードは個別のワークロード・オブジェクトとして格納されるため、多くのアドバイザ・タスク間で簡単に共有できます。ワークロード・オブジェクトは、アドバイザ・タスクによっていったん参照されると、すべてのアドバイザ・タスクからこのデータに対する依存性が削除されるまでは削除または変更できなくなります。ワークロード参照が削除されるのは、親アドバイザ・タスクが削除される場合か、ユーザーがアドバイザ・タスクからワークロード参照を手動で削除する場合です。

SQLアクセス・アドバイザのパフォーマンスは、使用状況に基づいたワークロードが使用可能な場合に最も高くなります。SQLアクセス・ワークロード・リポジトリには複数のワークロードを格納できるため、長期間にわたってデータベース・インスタンスの起動から停止までのライフサイクル全体について、実際のデータ・ウェアハウスまたはトランザクション処理環境の様々な使用状況を参照できます。

実際にワークロードのSQL文を定義する前に、CREATE_SQLWKLDプロシージャを使用してワークロードを作成する必要があります。次に、IMPORT_SQLWKLDプロシージャを使用してワークロードをロードします。特定のワークロードを削除するには、DELETE_SQLWKLDプロシージャをコールし、このプロシージャに有効なワークロード名を渡します。現在のユーザーのすべてのワークロードを削除するには、DELETE_SQLWKLDをコールし、定数値ADVISOR_ALLまたは%を渡します。

ワークロードの使用

CREATE_SQLWKLDプロシージャは、ワークロードを作成します。このプロシージャは、SQL文のインポートや更新などのその他のワークロード操作を実行する前に存在している必要があります。ワークロードは名前で識別されるため、操作に関連する一意の名前を定義する必要があります。

この構文は、次のとおりです。

DBMS_ADVISOR.CREATE_SQLWKLD (
   workload_name            IN OUT VARCHAR2,
   description              IN VARCHAR2 := NULL,
   template                 IN VARCHAR2 := NULL.
   is_template              IN VARCHAR2 := 'FALSE');

このプロシージャの使用例は、次のとおりです。

例 17-1    ワークロードの作成

VARIABLE workload_name VARCHAR2(255);
EXECUTE :workload_name := 'MYWORKLOAD';
EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD(:workload_name,'This is my first workload');

例 17-2    テンプレートからのワークロードの作成

  1. 変数を作成します。

    VARIABLE template_id NUMBER;
    VARIABLE template_name VARCHAR2(255);
    
    
  2. MY_WK_TEMPLATEと呼ばれるテンプレートを作成します。

    EXECUTE :template_name := 'MY_WK_TEMPLATE';
    EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD(:template_name, is_template=>'TRUE');
    
    
  3. テンプレートのパラメータを設定します。たとえば、次の例では、shスキーマ内の表のみをチューニングするフィルタを設定します。

    -- set USERNAME_LIST filter to SH
    EXECUTE DBMS_ADVISOR.SET_SQLWKLD_PARAMETER( -
       :template_name, 'USERNAME_LIST', 'SH');
    
    
  4. ここで、テンプレートを使用してワークロードを作成します。

    VARIABLE workload_name VARCHAR2(255);
    EXECUTE :workload_name := 'MYWORKLOAD';
    EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD ( -
       :workload_name, 'This is my first workload', 'MY_WK_TEMPLATE');
    
    

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

タスクとワークロードのリンク

推奨プロセスを開始する前に、タスクをワークロードにリンクする必要があります。これを行うには、ADD_SQKLWKLD_REFプロシージャを使用します。タスクとワークロードはそれぞれの名前を使用してリンクされます。このプロシージャは、アドバイザ・タスクとワークロード間のリンクを確立します。アドバイザ・タスクとワークロード間のリンクがいったん確立されると、ワークロードは削除できなくなります。 この構文は、次のとおりです。

DBMS_ADVISOR.ADD_SQLWKLD_REF (task_name      IN VARCHAR2,
                              workload_name  IN VARCHAR2);

次の例では、作成したMYTASKタスクをMYWORKLOAD SQLワークロードにリンクします。

EXECUTE DBMS_ADVISOR.ADD_SQLWKLD_REF('MYTASK', 'MYWORKLOAD');

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

ワークロードの内容の定義

ワークロードの作成後、ワークロードに情報を移入する必要があります。ワークロードは、データベースに使用されているSQL文で構成されるのが理想的です(仮想ワークロードである場合を除きます)。SQLアクセス・アドバイザは、次のソースからワークロードを取得できます。

SQLチューニング・セット

SQLチューニング・セットは、ワークロード・リポジトリにあるワークロードです。SQLチューニング・セットをSQLアクセス・アドバイザのワークロードとして使用するには、IMPORT_WORKLOAD_STSプロシージャを使用してこれをインポートします。このプロシージャの構文は、次のとおりです。

DBMS_ADVISOR.IMPORT_SQLWKLD_STS (workload_name  IN VARCHAR2,
                                 sts_owner      IN VARCHAR2,
                                 sts_name       IN VARCHAR2,
                                 import_mode    IN VARCHAR2 := 'NEW',
                                 priority       IN NUMBER := 2,
                                 saved_rows     OUT NUMBER,
                                 failed_rows    OUT NUMBER);

DBMS_ADVISOR.IMPORT_SQLWKLD_STS (workload_name  IN VARCHAR2,
                                 sts_name       IN VARCHAR2,
                                 import_mode    IN VARCHAR2 := 'NEW',
                                 priority       IN NUMBER := 2,
                                 saved_rows     OUT NUMBER,
                                 failed_rows    OUT NUMBER);

ワークロードが収集され、文にフィルタがかけられた後、SQLアクセス・アドバイザは、ワークロード内のDML文に関する使用状況統計を計算します。

次の例では、MY_STS_WORKLOADという名前のSQLチューニング・セットからワークロードを作成します。

VARIABLE sqlsetname  VARCHAR2(30);
VARIABLE workload_name VARCHAR2(30);
VARIABLE saved_stmts NUMBER;
VARIABLE failed_stmts NUMBER;
EXECUTE   :sqlsetname := 'MY_STS_WORKLOAD';
EXECUTE   :workload_name := 'MY_WORKLOAD';
EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD (:workload_name);
EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_STS (:workload_name , -
     :sqlsetname, 'NEW', 1, :saved_stmts, :failed_stmts);
ユーザー定義のワークロードのロード

ユーザー定義のワークロードをロードするには、IMPORT_SQLWKLD_USERプロシージャを使用します。このプロシージャは、ユーザー構成表からアプリケーション・ワークロードを収集するか、アプリケーション・ワークロードをアドバイザ・リポジトリに表示して保存します。owner_nametable_nameという2つのパラメータにより、ワークロードの取得元の表が識別されます。

ワークロードが格納されるスキーマ、表の名前、またはユーザー定義表の数には制限がありません。唯一の要件は、ユーザー表の形式がUSER_WORKLOAD表と一致することと(表17-1を参照)、ユーザーにはワークロード表またはビューに対するSELECTアクセス権があることが必要です。 この構文は、次のとおりです。

DBMS_ADVISOR.IMPORT_SQLWKLD_USER (
   workload_name         IN VARCHAR2,
   import_mode           IN VARCHAR2 := 'NEW',
   owner_name            IN VARCHAR2,
   table_name            IN VARCHAR2,
   saved_rows            OUT NUMBER,
   failed_rows           OUT NUMBER);

次の例では、ユーザー表SH.USER_WORKLOADを使用して、前に作成したMYWORKLOADワークロードをロードします。この表には、SQL文が移入されており、表17-1に指定されている形式に準拠していることが前提です。

VARIABLE saved_stmts NUMBER;
VARIABLE failed_stmts NUMBER;
EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_USER( -
   'MYWORKLOAD', 'NEW', 'SH', 'USER_WORKLOAD', :saved_stmts, :failed_stmts);

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

表 17-1    USER_WORKLOAD表の形式 
    デフォルト  コメント 
MODULE
 
VARCHAR2(64)
 

空の文字列 

アプリケーション・モジュール名です。 

ACTION
 
VARCHAR2(64)
 

空の文字列 

アプリケーションのアクションです。 

BUFFER_GETS
 
NUMBER
 

文のバッファ取得合計です。 

CPU_TIME
 
NUMBER
 

文の合計CPU時間(秒単位)です。 

ELAPSED_TIME
 
NUMBER
 

文の合計経過時間(秒単位)です。 

DISK_READS
 
NUMBER
 

文によって使用されたディスク読取り操作の合計回数です。 

ROWS_PROCESSED
 
NUMBER
 

SQL文によって処理された行の総数です。 

EXECUTIONS
 
NUMBER
 

文が実行された合計回数です。 

OPTIMIZER_COST
 
NUMBER
 

オプティマイザが計算した問合せの実行コスト値です。 

LAST_EXECUTION_DATE
 
DATE
 

SYSDATE 

問合せが最後に使用された日付です。デフォルトでは使用不可です。 

PRIORITY
 
NUMBER
 

2 

次のいずれかの値をとる必要があります。

1- HIGH、2- MEDIUMまたは3- LOW 

SQL_TEXT
 
CLOB or LONG or VARCHAR2
 

なし 

SQL文です。これは必須列です。 

STAT_PERIOD
 
NUMBER
 

実行統計に対応する時間(秒単位)です。 

USERNAME
 
VARCHAR(30)
 

現在のユーザー 

問合せを実行したユーザーです。これは必須列です。 

SQLキャッシュのワークロードのロード

SQLキャッシュのワークロードを取得するには、IMPORT_SQLWKLD_SQLCACHEプロシージャを使用します。このプロシージャがコールされると、SQLキャッシュの現在の内容が分析され、ワークロードに格納されます。IMPORT_SQLWKLD_SQLCACHEプロシージャにより、SQLキャッシュからSQLワークロードがロードされます。 この構文は、次のとおりです。

DBMS_ADVISOR.IMPORT_SQLWKLD_SQLCACHE (
   workload_name         IN VARCHAR2,
   import_mode           IN VARCHAR2,
   priority              IN NUMBER := 2,
   saved_rows            OUT NUMBER,
   failed_rows           OUT NUMBER);

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

次の例では、前に作成したMYWORKLOADワークロードをSQLキャッシュからロードします。ロードしたワークロード文の優先順位は、2(MEDIUM)です。

VARIABLE saved_stmts NUMBER;
VARIABLE failed_stmts NUMBER;
EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_SQLCACHE (-
   'MYWORKLOAD', 'APPEND', 2, :saved_stmts, :failed_stmts);

SQLアクセス・アドバイザでは、ワークロード情報をSQLキャッシュから取得できます。収集したデータが、インスタンス・パラメータcursor_sharingSIMILARまたはFORCEに設定されたサーバーから取得された場合、リテラル値が組み込まれたユーザー問合せは、システム生成のバインド変数が含まれる文に変換されます。SQLアクセス・アドバイザを使用してマテリアライズド・ビューを推奨する場合、サーバーのインスタンス・パラメータcursor_sharingEXACTに設定し、WHERE句を持つマテリアライズド・ビューが推奨されるようにする必要があります。

仮想ワークロードの使用方法

多くの場合、アプリケーション・ワークロードはまだ存在していません。このような場合、SQLアクセス・アドバイザは、現在の論理スキーマ設計を調べ、表間に定義されている関係に基づいて推奨事項を形成できます。このタイプのワークロードは、仮想ワークロードとも呼ばれます。SQLアクセス・アドバイザは、推奨事項の初期セットを生成し、アプリケーションをチューニングするための信頼できるベースとなります。

仮想ワークロードを使用する利点は、次のとおりです。

仮想ワークロードを使用する短所は、次のとおりです。

仮想ワークロードを正常にインポートするには、ターゲット・スキーマにディメンション情報が含まれている必要があります。この場合、IMPORT_SQLWKLD_SCHEMAプロシージャを使用します。 この構文は、次のとおりです。

DBMS_ADVISOR.IMPORT_SQLWKLD_SCHEMA (
   workload_name         IN VARCHAR2,
   import_mode           IN VARCHAR2 := 'NEW',
   priority              IN NUMBER := 2,
   saved_rows            OUT NUMBER,
   failed_rows           OUT NUMBER);

IMPORT_SQLWKLD_SCHEMAプロシージャとそのパラメータの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。このプロシージャを使用するには、外部プロシージャを構成する必要があります。

次の例では、SCHEMA_WKLDと呼ばれる仮想ワークロードを作成し、VALID_TABLE_LISTshに設定し、IMPORT_SQLWKLD_SCHEMAをコールして仮想ワークロードを生成します。

VARIABLE workload_name VARCHAR2(255);
VARIABLE saved_stmts NUMBER;
VARIABLE failed_stmts NUMBER;
EXECUTE :workload_name := 'SCHEMA_WKLD';
EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD(:workload_name);
EXECUTE DBMS_ADVISOR.SET_SQLWKLD_PARAMETER (:workload_name, -
                                            VALID_TABLE_LIST, 'SH');
EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_SCHEMA ( -
  :workload_name, 'NEW', 2, :saved_stmts, :failed_stmts);

IMPORT_SQLWKLD_SCHEMAを使用する場合、VALID_TABLE_LISTパラメータには、SCO%SCOTT.EMP%などのワイルドカードは使用できません。サポートされているワイルドカードの形式は、特定のスキーマ内のすべての表を指定するSCOTT.%のみです。

Oracle Database 9i サマリー・アドバイザのワークロードの使用方法

Oracle Database 9i サマリー・アドバイザを使用してワークロードを作成したとします。これらのワークロードをSQLアクセス・アドバイザにより使用できるようにするには、IMPORT_SQLWLD_SUMADVプロシージャを使用してこれらをインポートします。このプロシージャを使用するには、Oracle Database 9i のワークロードIDを知っている必要があります。

このプロシージャは、SQLワークロードをサマリー・アドバイザのワークロードから収集します。このプロシージャは、Oracle Database 9i サマリー・アドバイザのユーザーによるSQLアクセス・アドバイザへの移行をサポートすることを目的としています。 この構文は、次のとおりです。

DBMS_ADVISOR.IMPORT_SQLWKLD_SUMADV (
   workload_name         IN VARCHAR2,
   import_mode           IN VARCHAR2 := 'NEW',
   priority              IN NUMBER := 2,
   sumadv_id             IN NUMBER,
   saved_rows            OUT NUMBER,
   failed_rows           OUT NUMBER);

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

次の例では、Oracle Database 9i サマリー・アドバイザのワークロードからSQLワークロードを作成します。Oracle Database 9i のワークロードのworkload_idは、777です。

  1. 変数を作成します。

    VARIABLE workload_name VARCHAR2(255);
    VARIABLE saved_stmts NUMBER;
    VARIABLE failed_stmts NUMBER;
    
    
  2. WKLD_9Iという名前のワークロードを作成します。

    EXECUTE :workload_name := 'WKLD_9I';
    EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD(:workload_name);
    
    
  3. Oracle Database 9i サマリー・アドバイザからワークロードをインポートします。

    EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_SUMADV ( -
       :workload_name, 'NEW', 2, 777, :saved_stmts, :failed_stmts);
    
SQLアクセス・アドバイザのワークロードのパラメータ

ロード時にSQLワークロードにフィルタをかけるには、SET_SQLWKLD_PARAMETERを使用して『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』に記載されている1つ以上のパラメータを設定します。

次の例は、SQLワークロードのパラメータの設定を示しています。ここでは、SQL_LIMITを3、ORDER_LISTOPTIMIZER_COSTに設定します。つまり、ワークロードのインポート時には、文はOPTIMIZER_COSTで順序付けられ、上位3つの文が保持されます。

-- Order statements by OPTIMIZER_COST
EXECUTE DBMS_ADVISOR.SET_SQLWKLD_PARAMETER ( -
   'MYWORKLOAD', 'ORDER_LIST', 'OPTIMIZER_COST');
-- Max number of statements 3
EXECUTE DBMS_ADVISOR.SET_SQLWKLD_PARAMETER('MYWORKLOAD', 'SQL_LIMIT', 3);

ワークロードへのSQL文の追加

ワークロードをインポートするもう1つの方法は、SQL文を手動で指定し、ADD_SQLWKLD_STATEMENTプロシージャを使用してこれらをワークロードに追加する方法です。このプロシージャは、指定されたワークロードにSQL文を追加します。 この構文は、次のとおりです。

DBMS_ADVISOR.ADD_SQLWKLD_STATEMENT (
   workload_name       IN VARCHAR2,
   module              IN VARCHAR2,
   action              IN VARCHAR2,
   cpu_time            IN NUMBER := 0,
   elapsed_time        IN NUMBER := 0,
   disk_reads          IN NUMBER := 0,
   buffer_gets         IN NUMBER := 0,
   rows_processed      IN NUMBER := 0,
   optimizer_cost      IN NUMBER := 0,
   executions          IN NUMBER := 1,
   priority            IN NUMBER := 2,
   last_execution_date IN DATE := 'SYSDATE',
   stat_period         IN NUMBER := 0,
   username            IN VARCHAR2,
   sql_text            IN CLOB);

ADD_SQLWKLD_STATEMENTプロシージャとそのパラメータの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。次の例では、MYWORKLOADワークロードに文を1つ追加します。

VARIABLE sql_text VARCHAR2(400);
EXECUTE :sql_text := 'SELECT AVG(amount_sold) FROM sales';
EXECUTE DBMS_ADVISOR.ADD_SQLWKLD_STATEMENT ( -
   'MYWORKLOAD', 'MONTHLY', 'ROLLUP', priority=>1, executions=>10, -
    username => 'SH',  sql_text => :sql_text);

ワークロードのSQL文の削除

既存のSQL文を特定のワークロードから削除するには、DELETE_SQLWKLD_STATEMENTプロシージャを使用します。このプロシージャでは、sql_idによって指定した文を削除できます。

DBMS_ADVISOR.DELETE_SQLWKLD_STATEMENT (workload_name  IN VARCHAR2,
                                       sql_id         IN NUMBER);

次の例では、sql_idが10の文をMYWORKLOADから削除します。

EXECUTE DBMS_ADVISOR.DELETE_SQLWKLD_STATEMENT('MYWORKLOAD', 10);

ワークロードが現在アクティブなタスクによって参照されている場合、このワークロードは変更または削除できません。タスクは、初期状態にない場合アクティブであるとみなされます。タスクを初期状態に設定する方法の詳細は、RESET_TASKプロシージャを参照してください。 DELETE_SQLWKLD_STATEMENTプロシージャとそのパラメータの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。

ワークロードのSQL文の変更

ワークロードのSQL文を変更するには、UPDATE_SQLWKLD_STATEMENTプロシージャを使用します。このプロシージャは、指定したワークロード内の既存のSQL文を更新します。

このプロシージャでは、sql_idを指定してSQL文を更新できます。 この構文は、次のとおりです。

DBMS_ADVISOR.UPDATE_SQLWKLD_STATEMENT (
   workload_name     IN VARCHAR2,
   sql_id            IN NUMBER,
   application       IN VARCHAR2 := NULL,
   action            IN VARCHAR2 := NULL,
   priority          IN NUMBER := NULL,
   username          IN VARCHAR2 := NULL);

DBMS_ADVISOR.UPDATE_SQLWKLD_STATEMENT (
   workload_name     IN VARCHAR2,
   search            IN VARCHAR2,
   updated           OUT NUMBER,
   application       IN VARCHAR2 := NULL,
   action            IN VARCHAR2 := NULL,
   priority          IN NUMBER := NULL,
   username          IN VARCHAR2 := NULL);

次の例では、IDが10の文の優先順位を3に変更します。

EXECUTE DBMS_ADVISOR.UPDATE_SQLWKLD_STATEMENT('MYWORKLOAD', 10, priority=>3);
                                              

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

ワークロードのメンテナンス

ワークロードまたは実行可能なその他の操作には、次のようなものがあります。

ワークロード属性の設定

UPDATE_SQLWKLD_ATTRIBUTESは、ワークロード・オブジェクトまたはテンプレートの様々な属性を変更します。これには、ワークロードの説明、ワークロードがテンプレートであるか読取り専用であるかなどの属性があります。 この構文は、次のとおりです。

DBMS_ADVISOR.UPDATE_SQLWKLD_ATTRIBUTES (
   workload_name        IN VARCHAR2,
   new_name             IN VARCHAR2 := NULL,
   description          IN VARCHAR2 := NULL,
   read_only            IN VARCHAR2 := NULL,
   is_template          IN VARCHAR2 := NULL,
   how_created          IN VARCHAR2 := NULL);

次の例では、MYWORKLOADワークロードを読取り専用に変更します。

EXECUTE DBMS_ADVISOR.UPDATE_SQLWKLD_ATTRIBUTES ( -
   'MYWORKLOAD', read_only=> 'TRUE');

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

ワークロードのリセット

RESET_SQLWKLDプロシージャは、ワークロードを初期の開始ポイントにリセットします。これには、ワークロード・データに影響を与えずに、すべてのジャーナルおよびログ・メッセージの削除や不安定統計の再計算を実行できる利点があります。このプロシージャは、SQL文の追加や削除などのワークロード調整の後に実行する必要があります。次の例では、MYWORKLOADワークロードをリセットします。

EXECUTE DBMS_ADVISOR.RESET_SQLWKLD('MYWORKLOAD');

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

ワークロードとタスク間のリンクの削除

タスクまたはワークロードがそれぞれワークロードまたはタスクにリンクされている場合、これらを削除する前に、DELETE_SQLWKLD_REFプロシージャを使用して、タスクとワークロード間のリンクを削除する必要があります。次の例では、MYTASKタスクとMYWORKLOAD SQLワークロード間のリンクを削除します。

EXECUTE DBMS_ADVISOR.DELETE_SQLWKLD_REF('MYTASK', 'MYWORKLOAD');

ワークロードの削除

ワークロードが必要なくなった場合、DELETE_SQLWKLDプロシージャを使用してこれらを削除できます。すべてのワークロードまたは特定の収集を削除できますが、ワークロードがタスクにリンクされている場合は削除できません。

次のプロシージャは、特定のワークロードの削除例です。ここでは、リポジトリから既存のワークロードを削除します。

DBMS_ADVISOR.DELETE_SQLWKLD (workload_name  IN VARCHAR2);
EXECUTE DBMS_ADVISOR.DELETE_SQLWKLD('MYWORKLOAD');

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

推奨事項の処理

この項では、推奨事項の処理に関する次の側面について説明します。

推奨オプション

推奨事項を生成する前に、SET_TASK_PARAMETERプロシージャを使用してタスクのパラメータを最初に定義する必要があります。パラメータを定義しない場合、デフォルト値が使用されます。

タスクのパラメータを設定するには、SET_TASK_PARAMETERプロシージャを使用します。この構文は、次のとおりです。

DBMS_ADVISOR.SET_TASK_PARAMETER (
   task_name           IN VARCHAR2,
   parameter           IN VARCHAR2,
   value               IN [VARCHAR2 | NUMBER]);

タスク・パラメータは多数存在するため、関連するパラメータを識別しやすいように、これらのカテゴリ分けした表を表17-2に示します。

表 17-2    アドバイザのタスク・パラメータのタイプとその使用方法 
ワークロードのフィルタ  タスク構成  スキーマ属性  推奨オプション 
END_TIME
 
DAYS_TO_EXPIRE
 
DEF_INDEX_OWNER
 
DML_VOLATILITY
 
INVALID_ACTION_LIST
 
REPORT_DATE_FORMAT
 
DEF_INDEX_TABLESPACE
 
EVALUATION_ONLY
 
INVALID_MODULE_LIST
 
JOURNALING
 
DEF_MVIEW_OWNER
 
EXECUTION_TYPE
 
INVALID_SQLTRING_LIMIT
 

 
DEF_MVIEW_TABLESPACE
 
MODE
 
INVALID_TABLE_LIST
 

 
DEF_MVLOG_TABLSPACE
 
REFRESH_MODE
 
INVALID_USERNAME_LIST
 

 
INDEX_NAME_TEMPLATE
 
STORAGE_CHANGE
 
ORDER_LIST
 

 
MVIEW_NAME_TEMPLATE
 
CREATION_COST
 
SQL_LIMIT
 

 

 
WORKLOAD_SCOPE
 
START_TIME
 

 

 

 
TIME_LIMIT
 

 

 

 
VALID_ACTION_LIST
 

 

 

 
VALID_MODULE_LIST
 

 

 

 
VALID_SQLSTRING_LIST
 

 

 

 

VALID_TABLE_LIST
 

 

 

 

VALID_USERNAME_LIST
 

 

 

 

次の例では、MYTASKタスクの記憶域変更を100MBに設定します。これは、推奨事項の追加領域が100MBであることを示します。値0(ゼロ)は、割り当てられる追加領域がないことを示します。マイナス値は、指定した量だけアドバイザが現在の領域使用量を削減する必要があることを示しています。

EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER('MYTASK','STORAGE_CHANGE', 100000000);

次の例では、SH.SALESおよびSH.CUSTOMERS表を構成していないすべての問合せを、フィルタで除外するようにVALID_TABLE_LISTパラメータを設定します。

EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
   'MYTASK', 'VALID_TABLE_LIST', 'SH.SALES, SH.CUSTOMERS');

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

評価モード

タスクの実行時には、SQLアクセス・アドバイザは、問題解決と評価の2つのモードで動作します。デフォルトでは、SQLアクセス・アドバイザは、索引構造、マテリアライズド・ビューおよびマテリアライズド・ビュー・ログの拡張機能を検索し、アクセス方法の問題を解決しようとします。評価のみを行う場合、SQLアクセス・アドバイザは、指定されたワークロードが使用するアクセス構造についてのみコメントします。たとえば、問題解決の実行では、新しい索引の作成やマテリアライズド・ビュー・ログへの新しい列の追加などが推奨されますが、評価のみのシナリオでは、索引の保持やマテリアライズド・ビューの保持などの推奨事項のみが生成されます。評価を行う場合、アクセス方法の調整は考慮されません。評価では、既存のアクセス方法構造の参照や、指定されたワークロードによるこれらの使用方法の参照のみを行います。

推奨事項の生成

推奨事項を生成するには、タスク名とともにEXECUTE_TASKプロシージャを使用します。プロシージャが終了した後、DBA_ADVISOR_LOG表をチェックし、実際の実行ステータスや、生成された推奨事項およびアクションの数を確認できます。推奨事項は{DBA, USER}_ADVISOR_RECOMMENDATIONSでタスク名別に問い合せることができ、これら推奨事項のアクションは{DBA, USER}_ADVISOR_ACTIONSでタスク別に表示されます。

EXECUTE_TASKプロシージャ

このプロシージャでは、特定のタスクに対するSQLアクセス・アドバイザの分析または評価を実行します。タスク実行は同期操作であるため、操作が完了するか、ユーザー割込みが検出されるまで制御がユーザーに戻されません。タスクの実行が戻されると、実際の実行ステータスについてDBA_ADVISOR_LOG表をチェックできます。

EXECUTE_TASKを実行すると、推奨事項が生成されます。この場合、推奨事項は、マテリアライズド・ビュー・ログやマテリアライズド・ビューの作成などの1つ以上のアクションから構成されます。 この構文は、次のとおりです。

DBMS_ADVISOR.EXECUTE_TASK (task_name   IN VARCHAR2);

次に、このプロシージャの使用例を示します。

EXECUTE DBMS_ADVISOR.EXECUTE_TASK('MYTASK');

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

推奨事項の表示

SQLアクセス・アドバイザによって生成された各推奨事項は、(DBA, USER)_ADVISOR_RECOMMENDATIONSなどのいくつかのカタログ・ビューを使用して表示されます。ただし、GET_TASK_SCRIPTプロシージャを使用するか、またはEnterprise ManagerでSQLアクセス・アドバイザを使用する方が簡単です。この場合、推奨事項がグラフィック表示され、推奨事項が有用となるSQL文を簡単に参照するためのハイパーリンクが用意されています。SQLアクセス・アドバイザによって生成された各推奨事項は、推奨事項によってできるSQL文にリンクされています。

次の例は、アドバイザの実行によって生成される推奨事項(rec_id)とそのランクおよび全利点を示します。ランクとは、推奨事項がサポートする問合せの重要性の尺度です。利点とは、推奨事項を使用したすべての問合せの実行コスト(オプティマイザのコストの観点から)における改善結果です。

VARIABLE workload_name VARCHAR2(255); 
VARIABLE task_name VARCHAR2(255);
EXECUTE :task_name := 'MYTASK';
EXECUTE :workload_name := 'MYWORKLOAD'; 

SELECT REC_ID, RANK, BENEFIT
FROM USER_ADVISOR_RECOMMENDATIONS WHERE TASK_NAME = :task_name;

    REC_ID       RANK    BENEFIT
---------- ---------- ----------
         1          2       2754
         2          3       1222
         3          1       5499
         4          4        594

推奨事項が役立つ問合せを確認するには、DBA_*およびUSER_ADVISOR_SQLA_WK_STMTSビューを使用します。事前コストと事後コストの数は、それぞれ推奨されたアクセス構造の変更がある場合とない場合とで見積もられたオプティマイザのコスト(EXPLAIN PLANを参照)に関するものです。各問合せの推奨事項を表示するには、次の文を発行します。

SELECT sql_id, rec_id, precost, postcost,
       (precost-postcost)*100/precost AS percent_benefit
FROM USER_ADVISOR_SQLA_WK_STMTS
WHERE TASK_NAME = :task_name AND workload_name = :workload_name;

    SQL_ID     REC_ID    PRECOST   POSTCOST PERCENT_BENEFIT
---------- ---------- ---------- ---------- ---------------
       121          1       3003        249      91.7082917
       122          2       1404        182       87.037037
       123          3       5503          4      99.9273124
       124          4        730        136       81.369863

各推奨事項は1つ以上のアクションから構成されます。推奨事項の利点を得るには、これらのアクションをまとめて実装する必要があります。SQLアクセス・アドバイザでは、次のタイプのアクションを生成します。

CREATEアクションは、新しいアクセス構造に対応します。RETAIN推奨事項は、既存のアクセス構造を維持する必要があることを示します。DROP推奨事項が生成されるのは、WORKLOAD_SCOPEパラメータがFULLに設定されている場合のみです。GATHER STATSアクションは、DBMS_STATSプロシージャへのコールを生成し、新しく生成されたアクセス構造に関する統計を収集します。複数の推奨事項が同じアクションを参照していることがありますが、推奨事項のスクリプトの生成時に1回のみ各アクションが表示されます。

次の例では、この一連の推奨事項について個別アクションの数を確認できます。

SELECT 'Action Count', COUNT(DISTINCT action_id) cnt
FROM user_advisor_actions WHERE task_name = :task_name;

'ACTIONCOUNT        CNT   
------------ ----------  
Action Count          20

-- see the actions for each recommendations
SELECT rec_id, action_id, SUBSTR(command,1,30) AS command
FROM user_advisor_actions WHERE task_name = :task_name
ORDER BY rec_id, action_id;

    REC_ID  ACTION_ID COMMAND
---------- ---------- ------------------------------
         1          5 CREATE MATERIALIZED VIEW LOG
         1          6 ALTER MATERIALIZED VIEW LOG
         1          7 CREATE MATERIALIZED VIEW LOG
         1          8 ALTER MATERIALIZED VIEW LOG
         1          9 CREATE MATERIALIZED VIEW LOG
         1         10 ALTER MATERIALIZED VIEW LOG
         1         11 CREATE MATERIALIZED VIEW
         1         12 GATHER TABLE STATISTICS
         1         19 CREATE INDEX
         1         20 GATHER INDEX STATISTICS
         2          5 CREATE MATERIALIZED VIEW LOG
         2          6 ALTER MATERIALIZED VIEW LOG
         2          9 CREATE MATERIALIZED VIEW LOG
         ...
    

各アクションには、アクセス構造のプロパティに関連する複数の属性があります。各アクセス構造の名前と表領域は、必要に応じてattr1およびattr2にそれぞれ格納されます。新しい各アクセス構造が占有する領域は、num_attr1にあります。その他すべての属性は、アクションごとに異なります。

表17-3では、SQLアクセス・アドバイザのアクション情報をDBA_ADVISOR_ACTIONS内の該当する列にマップします。

表 17-3    SQLアクセス・アドバイザのアクション属性 
  ATTR1  ATTR2  ATTR3  ATTR4  ATTR5  ATTR6  NUM_ATTR1 

CREATE INDEX 

索引名 

索引表領域 

ターゲット表 

BITMAPまたはBTREE 

索引列
リスト/式 

未使用 

索引の記憶域のサイズ
(バイト単位) 

CREATE MATERIALIZED VIEW 

MV名 

MV表領域 

REFRESH COMPLETE REFRESH FASTREFRESH FORCENEVER REFRESH 

ENABLE QUERY REWRITEDISABLE QUERY REWRITE 

SQL SELECT文 

未使用 

MVの記憶域のサイズ
(バイト単位) 

CREATE MATERIALIZED VIEW LOG 

ターゲット表名 

MVログ 表領域 

ROWID PRIMARY KEYSEQUENCE OBJECT ID 

INCLUDING NEW VALUESEXCLUDING NEW VALUES 

表列リスト 

パーティション副次句 

未使用 

CREATE REWRITE EQUIVALENCE 

等価名 

チェック
サム値 

未使用 

未使用 

ソースSQL文 

等価SQL文 

未使用 

DROP INDEX 

索引名 

未使用 

未使用 

未使用 

索引列 

未使用 

索引の記憶域のサイズ
(バイト単位) 

DROP MATERIALIZED VIEW 

MV名 

未使用 

未使用 

未使用 

未使用 

未使用 

MVの記憶域のサイズ
(バイト単位) 

DROP MATERIALIZED VIEW LOG 

ターゲット表名 

未使用 

未使用 

未使用 

未使用 

未使用 

未使用 

RETAIN INDEX 

索引名 

未使用 

ターゲット表 

BITMAPまたはBTREE 

索引列 

未使用 

索引の記憶域のサイズ
(バイト単位) 

RETAIN MATERIALIZED VIEW 

MV名 

未使用 

REFRESH COMPLETEまたはREFRESH FAST 

未使用 

SQL SELECT文 

未使用 

MVの記憶域のサイズ
(バイト単位) 

RETAIN MATERIALIZED VIEW LOG 

ターゲット表名 

未使用 

未使用 

未使用 

未使用 

未使用 

未使用 

次のPL/SQLプロシージャを使用して、推奨事項の属性を出力できます。

CONNECT SH/SH;
CREATE OR REPLACE PROCEDURE show_recm (in_task_name IN VARCHAR2) IS 
CURSOR curs IS
  SELECT DISTINCT action_id, command, attr1, attr2, attr3, attr4
  FROM user_advisor_actions
  WHERE task_name = in_task_name
  ORDER BY action_id;
  v_action        number;
  v_command     VARCHAR2(32);
  v_attr1       VARCHAR2(4000);
  v_attr2       VARCHAR2(4000);
  v_attr3       VARCHAR2(4000);
  v_attr4       VARCHAR2(4000);
  v_attr5       VARCHAR2(4000);
BEGIN
  OPEN curs;
  DBMS_OUTPUT.PUT_LINE('=========================================');
  DBMS_OUTPUT.PUT_LINE('Task_name = ' || in_task_name);
  LOOP
     FETCH curs INTO  
       v_action, v_command, v_attr1, v_attr2, v_attr3, v_attr4 ;
   EXIT when curs%NOTFOUND;
   DBMS_OUTPUT.PUT_LINE('Action ID: ' || v_action);
   DBMS_OUTPUT.PUT_LINE('Command : ' || v_command);
   DBMS_OUTPUT.PUT_LINE('Attr1 (name)      : ' || SUBSTR(v_attr1,1,30));
   DBMS_OUTPUT.PUT_LINE('Attr2 (tablespace): ' || SUBSTR(v_attr2,1,30));
   DBMS_OUTPUT.PUT_LINE('Attr3             : ' || SUBSTR(v_attr3,1,30));
   DBMS_OUTPUT.PUT_LINE('Attr4             : ' || v_attr4);
   DBMS_OUTPUT.PUT_LINE('Attr5             : ' || v_attr5);
   DBMS_OUTPUT.PUT_LINE('----------------------------------------');  
   END LOOP;   
   CLOSE curs;      
   DBMS_OUTPUT.PUT_LINE('=========END RECOMMENDATIONS============');
END show_recm;
/
-- see what the actions are using sample procedure
set serveroutput on size 99999
EXECUTE show_recm(:task_name);
A fragment of a sample output from this procedure is as follows:
Task_name = MYTASK
Action ID: 1
Command : CREATE MATERIALIZED VIEW LOG 
Attr1 (name)      : "SH"."CUSTOMERS"
Attr2 (tablespace):
Attr3             : ROWID, SEQUENCE
Attr4             :  INCLUDING NEW VALUES
Attr5             :
----------------------------------------
..
----------------------------------------
Action ID: 15
Command : CREATE MATERIALIZED VIEW
Attr1 (name)      : "SH"."SH_MV$$_0004"
Attr2 (tablespace): "SH_MVIEWS"
Attr3             : REFRESH FAST WITH ROWID
Attr4             : ENABLE QUERY REWRITE
Attr5             :
----------------------------------------
..
----------------------------------------
Action ID: 19
Command : CREATE INDEX
Attr1 (name)      : "SH"."SH_IDX$$_0013"
Attr2 (tablespace): "SH_INDEXES"
Attr3             : "SH"."SH_MV$$_0002"
Attr4             : BITMAP
Attr5             :

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

SQLワークロードのジャーナル

分析プロセス(EXECUTE_TASK)の処理時に、SQLアクセス・アドバイザにより、分析に関して役に立つ情報がジャーナルに保存されます。ジャーナルを表示するには、USER_ADVISOR_JOURNALビューを使用します。情報の出力量は、JOURNALINGタスク・パラメータの設定に応じて異なります。

ワークロードのインポート時には、様々な情報メッセージがSQLワークロードのジャーナルに記録されます。これらのジャーナルを表示するには、USER_ADVISOR_SQLW_JOURNALを使用します。ジャーナルは、文がフィルタによってワークロードから除外された理由を特定するときに役に立ちます。たとえば、特定のSQL文が無効な表や統計が欠落している表を参照している場合や、特定のSQL文に権限エラーがある場合、この情報がジャーナルに記録されます。情報の出力量は、JOURNALINGパラメータの設定によって制御されます。

ジャーナルへの記録をオフにするには、次の文を発行します。

EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER('MYTASK', 'JOURNALING', 0);

ワークロードをインポートする前にジャーナルへの記録をオフにするには、次の文を発行します。

EXECUTE DBMS_ADVISOR.SET_SQLWKLD_PARAMETER('MYWORKLOAD', 'JOURNALING', 0);

情報メッセージのみを表示するには、次の文を発行します。

EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER('MYTASK', 'JOURNALING', 4);

致命的メッセージのみを表示するには、次の文を発行します。

EXECUTE DBMS_ADVISOR.SET_SQLWKLD_PARAMETER('MYWORKLOAD', 'JOURNALING', 1);

ジャーナル内の情報は診断のみを目的としており、将来のリリースでは変更される場合があります。ジャーナル内の情報は、アプリケーション内で使用しないでください。

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

推奨プロセスの停止

SQLアクセス・アドバイザがEXECUTE_TASKプロシージャを使用して推奨を行う時間が長すぎる場合、これを停止できます。停止するには、CANCEL_TASKプロシージャをコールし、この推奨プロセスのtask_nameを渡します。CANCEL_TASKを使用すると、推奨は行われません。また、推奨プロセスに割り込むには、INTERRUPT_TASKプロシージャを使用します。

タスクへの割込み

INTERRUPT_TASKプロシージャを使用すると、アドバイザ操作は通常の終了に達したものとして終了されます。これにより、ユーザーには、割込みポイントまでに形成された推奨事項が表示されます。

割り込まれたタスクは再開できません。 この構文は、次のとおりです。

DBMS_ADVISOR.INTERRUPT_TASK (task_name IN VARCHAR2);

次に、このプロシージャの使用例を示します。

EXECUTE DBMS_ADVISOR.INTERRUPT_TASK ('MY_TASK');
タスクの取消

CANCEL_TASKプロシージャを使用すると、現在実行中の操作が終了します。この場合、アドバイザ操作がコールに応答するのに数秒かかることがあります。すべてのアドバイザ・タスクのプロシージャは同期操作であるため、操作を取り消すには、別のデータベース・セッションを使用する必要があります。

取消コマンドは、取り消された操作の開始前の状態にタスクを効率的にリストアします。このため、取り消されたタスクまたはデータ・オブジェクトはリストアできません。この構文は、次のとおりです。

DBMS_ADVISOR.CANCEL_TASK (task_name   IN  VARCHAR2);

次に、このプロシージャの使用例を示します。

EXECUTE DBMS_ADVISOR.CANCEL_TASK('MYTASK');

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

推奨事項のマーキング

デフォルトでは、SQLアクセス・アドバイザのすべての推奨事項は実装可能な状態にありますが、MARK_RECOMMENDATIONプロシージャを使用すると、選択した推奨事項をスキップまたは除外できます。MARK_RECOMMENDATIONを使用すると、REJECTまたはIGNORE設定で推奨事項に注釈をつけることができます。これにより、プロシージャの実装時にGET_TASK_SCRIPTによってこの推奨事項はスキップされます。 この構文は、次のとおりです。

DBMS_ADVISOR.MARK_RECOMMENDATION (
   task_name          IN VARCHAR2
   id                 IN NUMBER,
   action             IN VARCHAR2);

次の例では、IDが2の推奨事項をREJECTとしてマークします。この推奨事項と任意の依存推奨事項は、スクリプトに表示されません。

EXECUTE DBMS_ADVISOR.MARK_RECOMMENDATION('MYTASK', 2, 'REJECT');

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

推奨事項の変更

UPDATE_REC_ATTRIBUTESプロシージャを使用すると、SQLアクセス・アドバイザにより、分析操作時に索引やマテリアライズド・ビューなどの新しいオブジェクトに名前が付けられ、所有権が割り当てられます。ただし、必ずしも適切な名前が選択されるとはかぎらないため、新しいオブジェクトの所有者、名前および表領域の値を手動で設定できます。既存のデータベース・オブジェクトを参照している推奨事項の場合、所有者と名前の値は変更できません。 この構文は、次のとおりです。

DBMS_ADVISOR.UPDATE_REC_ATTRIBUTES (
   task_name            IN VARCHAR2
   rec_id               IN NUMBER,
   action_id            IN NUMBER,
   attribute_name       IN VARCHAR2,
   value                IN VARCHAR2);

attribute_nameパラメータには、次の値を使用できます。

次の例では、推奨事項ID 1、アクションID 1のTABLESPACE属性をSH_MVIEWSに変更します。

EXECUTE DBMS_ADVISOR.UPDATE_REC_ATTRIBUTES('MYTASK', 1, 1, - 
                                           'TABLESPACE', 'SH_MVIEWS');

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

SQLスクリプトの生成

推奨事項を表示するためにメタデータを問い合せるもう1つの方法は、GET_TASK_SCRIPTプロシージャを使用して推奨事項のSQL文のスクリプトを作成する方法です。この結果生成されるスクリプトは実行可能SQLファイルで、DROPCREATEおよびALTER文を含めることができます。新しいオブジェクトの場合、マテリアライズド・ビューの名前、マテリアライズド・ビュー・ログおよび索引は、ユーザー指定の名前テンプレートを使用して自動的に生成されます。生成されたSQLスクリプトは、実行する前に見直す必要があります。

ネーミング規則(MVIEW_NAME_TEMPLATEおよびINDEX_NAME_TEMPLATE)、これらの新しいオブジェクトの所有者(DEF_INDEX_OWNERおよびDEF_MVIEW_OWNER)、表領域(DEF_MVIEW_TABLESPACEおよびDEF_INDEX_TABLESPACE)を制御するタスク・パラメータは4つあります。

次の例は、推奨事項のスクリプトが含まれるCLOBを生成する方法を示します。

EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT('MYTASK'), - 
               'ADVISOR_RESULTS', 'advscript.sql'); 

スクリプトをファイルに保存するには、CREATE_FILEプロシージャにスクリプトの格納先を示すディレクトリ・パスを指定する必要があります。また、このディレクトリには読取りおよび書込み権限を付与する必要があります。次の例は、CLOBアドバイザ・スクリプトをファイルに保存する方法を示します。

-- create a directory and grant permissions to read/write to it
CONNECT SH/SH;
CREATE DIRECTORY ADVISOR_RESULTS AS '/mydir';
GRANT READ ON DIRECTORY ADVISOR_RESULTS TO PUBLIC;
GRANT WRITE ON DIRECTORY ADVISOR_RESULTS TO PUBLIC;

次の例は、このスクリプトによって生成されたスクリプトのフラグメントです。また、このスクリプトには、推奨されたアクセス構造に関する統計を収集するPL/SQLコールが含まれ、最後に推奨事項をIMPLEMENTEDとしてマークします。

Rem  Access Advisor V10.1.0.0.0 - Production
Rem  
Rem  Username:        SH
Rem  Task:            MYTASK
Rem  Execution date:  15/04/2005 11:35
Rem  
set feedback 1
set linesize 80
set trimspool on
set tab off
set pagesize 60
whenever sqlerror CONTINUE

CREATE MATERIALIZED VIEW LOG ON "SH"."PRODUCTS"
    WITH ROWID, SEQUENCE("PROD_ID","PROD_SUBCATEGORY")
    INCLUDING NEW VALUES;
ALTER MATERIALIZED VIEW LOG FORCE ON "SH"."PRODUCTS"
    ADD ROWID, SEQUENCE("PROD_ID","PROD_SUBCATEGORY")
    INCLUDING NEW VALUES;
..
CREATE MATERIALIZED VIEW "SH"."MV$$_00510002"
    REFRESH FAST WITH ROWID
    ENABLE QUERY REWRITE
    AS SELECT SH.CUSTOMERS.CUST_STATE_PROVINCE C1, COUNT(*) M1 FROM
SH.CUSTOMERS WHERE (SH.CUSTOMERS.CUST_STATE_PROVINCE = 'CA') GROUP
BY SH.CUSTOMERS.CUST_STATE_PROVINCE;
BEGIN
  DBMS_STATS.GATHER_TABLE_STATS('"SH"', '"MV$$_00510002"', NULL, 
     DBMS_STATS.AUTO_SAMPLE_SIZE);
END;
/
..
CREATE BITMAP INDEX "SH"."MV$$_00510004_IDX$$_00510013"
    ON "SH"."MV$$_00510004" ("C4");
whenever sqlerror EXIT SQL.SQLCODE
BEGIN
  DBMS_ADVISOR.MARK_RECOMMENDATION('"MYTASK"',1,'IMPLEMENTED');
  DBMS_ADVISOR.MARK_RECOMMENDATION('"MYTASK"',2,'IMPLEMENTED');
  DBMS_ADVISOR.MARK_RECOMMENDATION('"MYTASK"',3,'IMPLEMENTED');
  DBMS_ADVISOR.MARK_RECOMMENDATION('"MYTASK"',4,'IMPLEMENTED');
END;
/

関連項目:

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

推奨事項が必要なくなった場合

RESET_TASKプロシージャは、タスクを初期の開始ポイントにリセットします。これにより、すべての推奨事項と中間データがタスクから削除されます。実際のタスクのステータスは、INITIALに設定されます。 この構文は、次のとおりです。

DBMS_ADVISOR.RESET_TASK (task_name     IN VARCHAR2);

次に、このプロシージャの使用例を示します。

EXECUTE DBMS_ADVISOR.RESET_TASK('MYTASK');

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

クイック・チューニングの実行

単一のSQL文のみをチューニングする場合、QUICK_TUNEプロシージャでは、task_nameとSQL文を入力できます。次に、タスクとワークロードが作成され、このタスクが実行されます。QUICK_TUNEを使用しても、結果に違いはありません。結果はEXECUTE_TASKを使用する場合とまったく同じです。チューニング対象のSQL文が1つのみである場合、この方法を使用した方が簡単です。 この構文は、次のとおりです。

DBMS_ADVISOR.QUICK_TUNE (
   advisor_name           IN VARCHAR2,
   task_name              IN VARCHAR2,
   attr1                  IN CLOB,
   attr2                  IN VARCHAR2 := NULL,
   attr3                  IN NUMBER := NULL,
   task_or_template       IN VARCHAR2 := NULL);

次の例は、単一のSQL文をクイック・チューニングする方法を示しています。

VARIABLE task_name VARCHAR2(255);
VARIABLE sql_stmt VARCHAR2(4000);
EXECUTE :sql_stmt := 'SELECT COUNT(*) FROM customers 
                      WHERE cust_state_province=''CA''';
EXECUTE :task_name  := 'MY_QUICKTUNE_TASK';
EXECUTE DBMS_ADVISOR.QUICK_TUNE(DBMS_ADVISOR.SQLACCESS_ADVISOR, -
              :task_name, :sql_stmt);

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

タスクの管理

推奨事項が生成されるたびにタスクが作成され、それらのタスクに対してメンテナンスが実行されない場合、タスク数は時間の経過とともに増加し、記憶域領域を占めるようになります。タスクの中には、誤って削除しないように保持する必要のあるタスクがある場合もあります。このため、タスクに対して実行可能な管理操作がいくつか用意されています。

タスク属性の更新

UPDATE_TASK_ATTRIBUTESプロシージャを使用すると、次の操作ができます。

この構文は、次のとおりです。

DBMS_ADVISOR.UPDATE_TASK_ATTRIBUTES (
   task_name          IN VARCHAR2
   new_name           IN VARCHAR2 := NULL,
   description        IN VARCHAR2 := NULL,
   read_only          IN VARCHAR2 := NULL,
   is_template        IN VARCHAR2 := NULL,
   how_created        IN VARCHAR2 := NULL);

次の例では、タスクMYTASKの名前がTUNING1に更新されます。

EXECUTE DBMS_ADVISOR.UPDATE_TASK_ATTRIBUTES('MYTASK', 'TUNING1');

次の例では、タスクTUNING1が読取り専用に設定されます。

EXECUTE DBMS_ADVISOR.UPDATE_TASK_ATTRIBUTES('TUNING1', read_only => 'TRUE');

次の例では、タスクMYTASKがテンプレートとして設定されます。

EXECUTE DBMS_ADVISOR.UPDATE_TASK_ATTRIBUTES('TUNING1', is_template=>'TRUE');

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

タスクの削除

DELETE_TASKプロシージャでは、アドバイザの既存のタスクがリポジトリから削除されます。 この構文は、次のとおりです。

DBMS_ADVISOR.DELETE_TASK (task_name  IN VARCHAR2);

次に、このプロシージャの使用例を示します。

EXECUTE DBMS_ADVISOR.DELETE_TASK('MYTASK');

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

DAYS_TO_EXPIREパラメータの設定

タスクやワークロード・オブジェクトが作成されると、パラメータDAYS_TO_EXPIREが30に設定されます。この値は、タスクやオブジェクトがシステムによって自動的に削除されるまでの日数を示しています。タスクやワークロードを無期限に保持するには、DAYS_TO_EXPIREパラメータをADVISOR_UNLIMITEDに設定する必要があります。

SQLアクセス・アドバイザの定数の使用方法

SQLアクセス・アドバイザでは、表17-4に示されている定数を使用できます。

表 17-4    SQLアクセス・アドバイザの定数 
定数  説明 
ADVISOR_ALL
 

すべての可能な値を示すために使用する値。文字列パラメータでは、この値はワイルドカード文字である%と同等です。 

ADVISOR_CURRENT
 

現在の時刻またはアクティブな要素セットを示します。通常、これは時間パラメータで使用します。 

ADVISOR_DEFAULT
 

デフォルト値を示します。通常、タスクまたはワークロード・パラメータの設定時に使用します。 

ADVISOR_UNLIMITED
 

無制限な数値を表す値です。 

ADVISOR_UNUSED
 

未使用のエンティティを表す値。パラメータがADVISOR_UNUSEDに設定されている場合、現在の操作には影響しません。通常、この値はパラメータを依存操作に対して未使用に設定するために使用します。 

SQLACCESS_GENERAL
 

SQLアクセスの汎用タスク・テンプレートのデフォルト名を指定します。このテンプレートでは、DML_VOLATILITYタスク・パラメータをTRUEに、またEXECUTION_TYPEFULLに設定します。 

SQLACCESS_OLTP
 

SQLアクセスのOLTPタスク・テンプレートのデフォルト名を指定します。このテンプレートでは、DML_VOLATILITYタスク・パラメータをTRUEに、またEXECUTION_TYPEINDEX ONLYに設定します。 

SQLACCESS_WAREHOUSE
 

SQLアクセスのウェアハウス・タスク・テンプレートのデフォルト名を指定します。このテンプレートでは、DML_VOLATILITYタスク・パラメータをFALSEに、またEXECUTION_TYPEFULLに設定します。 

SQLACCESS_ADVISOR
 

SQLアクセス・アドバイザの正式名称を格納します。プロシージャでアドバイザ名が引数として必要な場合、これを使用できます。 

SQLアクセス・アドバイザの使用例

この項では、SQLアクセス・アドバイザの一般的な使用例について説明します。Oracle Databaseでは、この章の例を含むaadvdemo.sqlというスクリプトが提供されています。

ユーザー定義のワークロードの推奨事項

次の例では、ユーザー定義表SH.USER_WORKLOADからワークロードがインポートされます。次に、MYTASKというタスクが作成され、記憶域上限が100 MBに設定されて、タスクが実行されます。PL/SQLプロシージャによって、推奨事項が印刷されます。最後にスクリプトが生成されます。これを使用して、推奨事項を実装できます。

手順 1    USER_WORKLOAD表の準備

次のSQL文で、USER_WORKLOAD表がロードされます。

CONNECT SH/SH;
-- aggregation with selection
INSERT INTO user_workload (username, module, action, priority, sql_text)
VALUES ('SH', 'Example1', 'Action', 2, 
'SELECT   t.week_ending_day, p.prod_subcategory, 
          SUM(s.amount_sold) AS dollars, s.channel_id, s.promo_id
 FROM sales s, times t, products p WHERE s.time_id = t.time_id
 AND s.prod_id = p.prod_id AND s.prod_id > 10 AND s.prod_id < 50
 GROUP BY t.week_ending_day, p.prod_subcategory, 
          s.channel_id, s.promo_id')
/

-- aggregation with selection
INSERT INTO user_workload (username, module, action, priority, sql_text)
VALUES ('SH', 'Example1', 'Action', 2, 
 'SELECT   t.calendar_month_desc, SUM(s.amount_sold) AS dollars
  FROM     sales s , times t
  WHERE    s.time_id = t.time_id
  AND    s.time_id between TO_DATE(''01-JAN-2000'', ''DD-MON-YYYY'')
                       AND TO_DATE(''01-JUL-2000'', ''DD-MON-YYYY'')
GROUP BY t.calendar_month_desc')
/

--Load all SQL queries.
INSERT INTO user_workload (username, module, action, priority, sql_text)
VALUES ('SH', 'Example1', 'Action', 2, 
'SELECT ch.channel_class, c.cust_city, t.calendar_quarter_desc,
   SUM(s.amount_sold) sales_amount
FROM sales s, times t, customers c, channels ch
WHERE s.time_id = t.time_id AND s.cust_id = c.cust_id
AND s.channel_id = ch.channel_id AND c.cust_state_province = ''CA''
AND   ch.channel_desc IN (''Internet'',''Catalog'')
AND   t.calendar_quarter_desc IN (''1999-Q1'',''1999-Q2'')
GROUP BY ch.channel_class, c.cust_city, t.calendar_quarter_desc')
/

-- order by
INSERT INTO user_workload (username, module, action, priority, sql_text)
VALUES ('SH', 'Example1', 'Action', 2, 
  'SELECT c.country_id, c.cust_city, c.cust_last_name
FROM customers c WHERE c.country_id IN (52790, 52789)
ORDER BY c.country_id, c.cust_city, c.cust_last_name')
/
COMMIT;

CONNECT SH/SH;
set serveroutput on;

VARIABLE task_id NUMBER;
VARIABLE task_name VARCHAR2(255);
VARIABLE workload_name VARCHAR2(255);
VARIABLE saved_stmts NUMBER;
VARIABLE failed_stmts NUMBER;
手順 2    ワークロードMYWORKLOADの作成
EXECUTE :workload_name := 'MYWORKLOAD';
EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD(:workload_name);
手順 3    ユーザー定義表SH.USER_WORKLOADからのワークロードのロード
EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_USER (:workload_name, 'APPEND', 'SH', -
   'USER_WORKLOAD', :saved_stmts, :failed_stmts);
PRINT :saved_stmts;
PRINT :failed_stmts;
手順 4    タスクMYTASKの作成
EXECUTE :task_name := 'MYTASK';
EXECUTE DBMS_ADVISOR.CREATE_TASK('SQL Access Advisor', :task_id, :task_name);
手順 5    タスク・パラメータの設定
EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER(:task_name, 'STORAGE_CHANGE', 100);
EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
   :task_name, 'EXECUTION_TYPE', 'INDEX_ONLY');
手順 6    ワークロードとタスクの間のリンクの作成
EXECUTE DBMS_ADVISOR.ADD_SQLWKLD_REF(:task_name, :workload_name);
手順 7    タスクの実行
EXECUTE DBMS_ADVISOR.EXECUTE_TASK(:task_name);
手順 8    推奨事項の表示
-- See the number of recommendations and the status of the task.
SELECT rec_id, rank, benefit
FROM user_advisor_recommendations WHERE task_name = :task_name;

詳細は、「推奨事項の表示」または「SQLスクリプトの生成」を参照してください。

-- See recommendation for each query.
SELECT sql_id, rec_id, precost, postcost,
      (precost-postcost)*100/precost AS percent_benefit
FROM user_advisor_sqla_wk_stmts
WHERE task_name = :task_name AND workload_name = :workload_name;

-- See the actions for each recommendations.
SELECT rec_id, action_id, SUBSTR(command,1,30) AS command
FROM user_advisor_actions
WHERE task_name = :task_name
ORDER BY rec_id, action_id;

-- See what the actions are using sample procedure.
SET SERVEROUTPUT ON SIZE 99999
EXECUTE show_recm(:task_name);
手順 9    推奨事項を実装するためのスクリプトの生成
EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT(:task_name),-
                                 'ADVISOR_RESULTS', 'Example1_script.sql');

タスク・テンプレートを使用した推奨事項の生成

次の例では、テンプレートを作成し、それを使用してタスクを作成します。 次にこのタスクを使用して、「ユーザー定義のワークロードの推奨事項」と同様に、ユーザー定義の表から推奨事項が生成されます。

CONNECT SH/SH;
VARIABLE template_id NUMBER;
VARIABLE template_name VARCHAR2(255);
手順 1    テンプレートMY_TEMPLATEの作成
EXECUTE :template_name := 'MY_TEMPLATE';
EXECUTE DBMS_ADVISOR.CREATE_TASK ( -
   'SQL Access Advisor',:template_id, :template_name, is_template=>'TRUE');
手順 2    テンプレート・パラメータの設定

推奨される索引およびマテリアライズド・ビューのネーミング規則を設定します。

EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
   :template_name,  'INDEX_NAME_TEMPLATE', 'SH_IDX$$_<SEQ>');
EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
   :template_name, 'MVIEW_NAME_TEMPLATE', 'SH_MV$$_<SEQ>');

--Set default owners for recommended indexes/materialized views.
EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
   :template_name, 'DEF_INDEX_OWNER', 'SH');
EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
   :template_name, 'DEF_MVIEW_OWNER', 'SH');

--Set default tablespace for recommended indexes/materialized views.
EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
   :template_name, 'DEF_INDEX_TABLESPACE', 'SH_INDEXES');
EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER ( -
   :template_name, 'DEF_MVIEW_TABLESPACE', 'SH_MVIEWS');
手順 3    テンプレートを使用したタスクの作成
VARIABLE task_id NUMBER;
VARIABLE task_name VARCHAR2(255);
EXECUTE :task_name := 'MYTASK';
EXECUTE DBMS_ADVISOR.CREATE_TASK ( -
   'SQL Access Advisor', :task_id, :task_name, template => 'MY_TEMPLATE');

--See the parameter settings for task
SELECT parameter_name, parameter_value
FROM user_advisor_parameters
WHERE task_name = :task_name AND (parameter_name LIKE '%MVIEW%' 
   OR parameter_name LIKE '%INDEX%');
手順 4    ワークロードMYWORKLOADの作成
VARIABLE workload_name VARCHAR2(255);
VARIABLE saved_stmts NUMBER;
VARIABLE failed_stmts NUMBER;
EXECUTE :workload_name := 'MYWORKLOAD';
EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD(:workload_name);
手順 5    ユーザー定義表SH.USER_WORKLOADからのワークロードのロード
EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_USER ( -
   :workload_name, 'APPEND', 'SH', 'USER_WORKLOAD', :saved_stmts,:failed_stmts);
手順 6    ワークロードとタスクの間のリンクの作成
EXECUTE DBMS_ADVISOR.ADD_SQLWKLD_REF(:task_name, :workload_name);
手順 7    タスクの実行
EXECUTE DBMS_ADVISOR.EXECUTE_TASK(:task_name);
手順 8    スクリプトの生成
EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT(:task_name),-
                                 'ADVISOR_RESULTS', 'Example2_script.sql');

SQLキャッシュからのワークロードのフィルタリング

次の例では、SQLキャッシュからワークロードを収集する方法を示します。まず、一連のSQL文でキャッシュをロードします。次に、いくつかのフィルタを設定してそれらの文のサブセットのみを選択し、SQLアクセス・アドバイザのワークロードにインポートします。その後、ワークロードを使用して、推奨事項を生成します。

手順 1    SQLキャッシュのロード

次の文が実行され、SQLキャッシュにロードされます。

CONNECT / AS SYSDBA

--Clear any prior contents of the cache.
ALTER SYSTEM FLUSH SHARED_POOL;
CONNECT SH/SH;

SELECT   t.calendar_month_desc, SUM(s.amount_sold) AS dollars
FROM     sales s, times t WHERE s.time_id = t.time_id
AND  s.time_id between TO_DATE('01-JAN-2000', 'DD-MON-YYYY')
                       AND TO_DATE('01-JUL-2000', 'DD-MON-YYYY')
GROUP BY t.calendar_month_desc;

-- Order by
SELECT c.country_id, c.cust_city, c.cust_last_name
FROM customers c WHERE c.country_id IN ('52790', '52789')
ORDER BY c.country_id, c.cust_city, c.cust_last_name;

-- Queries to illustrate filtering
CONNECT scott/tiger;
SELECT e.ename, d.dname
FROM emp e, dept d WHERE e.deptno = d.deptno;

SELECT COUNT(*) FROM dept;

CONNECT sh/sh
VARIABLE task_id NUMBER;
VARIABLE task_name VARCHAR2(255);
VARIABLE workload_name VARCHAR2(255);
VARIABLE saved_stmts NUMBER;
VARIABLE failed_stmts NUMBER;
手順 2    ワークロードMY_CACHE_WORKLOADの作成
EXECUTE :workload_name := 'MY_CACHE_WORKLOAD';
EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD(:workload_name);
手順 3    フィルタの設定

SH表を含むSQL文のみのロード

EXECUTE DBMS_ADVISOR.SET_SQLWKLD_PARAMETER ( -
   :workload_name, 'USERNAME_LIST', 'SH');
手順 4    SQLキャッシュからのワークロードのロード
EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_SQLCACHE ( -
   :workload_name, 'APPEND', 2, :saved_stmts, :failed_stmts);
PRINT :saved_stmts;
PRINT :failed_stmts;

--See the workload statements in catalog views
SELECT num_select_stmt, create_date
FROM user_advisor_sqlw_sum
WHERE workload_name = :workload_name;

SELECT sql_id, username, optimizer_cost, SUBSTR(sql_text, 1, 30)
FROM user_advisor_sqlw_stmts
WHERE workload_name = :workload_name
ORDER BY sql_id;
手順 5    ワークロードへの文の追加
EXECUTE DBMS_ADVISOR.ADD_SQLWKLD_STATEMENT (:workload_name, username => 'SH', -
    priority => 1, executions => 10,  sql_text =>  -
   'select count(*) from customers where cust_state_province=''CA''');

SELECT num_select_stmt, create_date
FROM user_advisor_sqlw_sum
WHERE workload_name = :workload_name;
手順 6    タスクMYTASKの作成
EXECUTE :task_name := 'MYTASK';
EXECUTE DBMS_ADVISOR.CREATE_TASK ('SQL Access Advisor', :task_id, :task_name);
手順 7    ワークロードとタスクの間のリンクの作成
EXECUTE DBMS_ADVISOR.ADD_SQLWKLD_REF(:task_name, :workload_name);
手順 8    タスクの実行
EXECUTE DBMS_ADVISOR.EXECUTE_TASK(:task_name);
手順 9    スクリプトの生成
EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT(:task_name),-
                                 'ADVISOR_RESULTS', 'Example3_script.sql');

索引およびマテリアライズド・ビューの現在の使用状況の評価

この例では、SQLアクセス・アドバイザを使用して、既存の索引およびマテリアライズド・ビューの使用率を評価する方法を示します。 「ユーザー定義のワークロードの推奨事項」に記載されているように、ワークロードをUSER_WORKLOAD表にロードするとします。(特定のワークロードによって)現在使用されている索引およびマテリアライズド・ビューは、SQLアクセス・アドバイザの推奨事項でRETAINアクションとして表示されます。

CONNECT SH/SH;
VARIABLE task_id NUMBER;
VARIABLE task_name VARCHAR2(255);
VARIABLE workload_name VARCHAR2(255);
VARIABLE saved_stmts NUMBER;
VARIABLE failed_stmts NUMBER;
手順 1    ワークロードWORKLOADの作成
EXECUTE :workload_name := 'MYWORKLOAD';
EXECUTE DBMS_ADVISOR.CREATE_SQLWKLD(:workload_name);
手順 2    ユーザー定義表SH.USER_WORKLOADからのワークロードのロード
EXECUTE DBMS_ADVISOR.IMPORT_SQLWKLD_USER ( -
   :workload_name, 'APPEND', 'SH','USER_WORKLOAD', :saved_stmts, :failed_stmts);

PRINT :saved_stmts;
PRINT :failed_stmts;
手順 3    タスクMY_EVAL_TASKの作成
EXECUTE :task_name := 'MY_EVAL_TASK';
EXECUTE DBMS_ADVISOR.CREATE_TASK ('SQL Access Advisor', :task_id, :task_name);
手順 4    ワークロードとタスクの間のリンクの作成
EXECUTE DBMS_ADVISOR.ADD_SQLWKLD_REF(:task_name, :workload_name);
手順 5    EVALUATION ONLYタスクを示すタスク・パラメータの設定
EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER (:task_name, 'EVALUATION_ONLY', 'TRUE');
手順 6    タスクの実行
EXECUTE DBMS_ADVISOR.EXECUTE_TASK(:task_name);
手順 7    評価結果の表示
--See the number of recommendations and the status of the task.
SELECT rec_id, rank, benefit
FROM user_advisor_recommendations WHERE task_name = :task_name;

--See the actions for each recommendation.
SELECT rec_id, action_id, SUBSTR(command,1,30) AS command, attr1 AS name
FROM user_advisor_actions WHERE task_name = :task_name
ORDER BY rec_id, action_id;

高速リフレッシュとクエリー・リライトのためのマテリアライズド・ビューのチューニング

高速リフレッシュおよびクエリー・リライトのために最適化されたマテリアライズド・ビューを作成するには、いくつかのDBMS_MVIEWプロシージャが役立ちます。EXPLAIN_MVIEWプロシージャではマテリアライズド・ビューの高速リフレッシュおよび通常のクエリー・リライトが可能かどうかが、またEXPLAIN_REWRITEプロシージャではクエリー・リライトが行われるかどうかがわかります。ただし、いずれのプロシージャでも、高速リフレッシュやクエリー・リライトの実行方法は示されません。

マテリアライズド・ビューをさらに使いやすくするため、TUNE_MVIEWプロシージャでは、CREATE MATERIALIZED VIEW文を最適化する方法と、高速リフレッシュや通常のクエリー・リライトのためのその他の要件(マテリアライズド・ビュー・ログやリライト同値化関係など)を満たす方法が示されます。TUNE_MVIEWにより、CREATE MATERIALIZED VIEW文の分析と処理が行われ、2つの出力結果(マテリアライズド・ビューの実装とマテリアライズド・ビュー作成操作の取消し)が生成されます。この2つの出力結果は、Oracleのビューからアクセスできる他、SQLアクセス・アドバイザで作成された外部スクリプト・ファイルに保存することもできます。これらの外部スクリプト・ファイルを実行すると、マテリアライズド・ビューを実装できます。

TUNE_MVIEWプロシージャを使用すると、マテリアライズド・ビューの詳しい知識がない場合でも、アプリケーションでマテリアライズド・ビューを作成できます。このプロシージャによって、マテリアライズド・ビューと必要なコンポーネント(マテリアライズド・ビュー・ログなど)は正しく作成されます。

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

DBMS_ADVISOR.TUNE_MVIEWプロシージャ

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

TUNE_MVIEWの構文と操作

TUNE_MVIEWの構文は次のとおりです。

DBMS_ADVISOR.TUNE_MVIEW (
  task_name IN OUT VARCHAR2, mv_create_stmt IN [CLOB | VARCHAR2])

TUNE_MVIEWプロシージャでは、task_namemv_create_stmtという2つの入力パラメータが使用されます。task_nameはユーザー提供のタスク識別子で、出力結果へのアクセスに使用されます。mv_create_stmtは、チューニングが行われる完全なCREATE MATERIALIZED VIEW文です。入力されたCREATE MATERIALIZED VIEW文にREFRESH FAST句またはENABLE QUERY REWRITE句の一方あるいは両方が含まれない場合、TUNE_MVIEWでは、デフォルトであるREFRESH FORCE句およびDISABLE QUERY REWRITE句を使用して文をチューニングし、可能な場合は高速リフレッシュ、それ以外の場合は完全リフレッシュが実行されます。

TUNE_MVIEWプロシージャでは、内部に任意の問合せ定義を持つことができる、様々なCREATE MATERIALIZED VIEW文が処理されます。この問合せ定義は、単純なSELECT文である場合も、集合演算子やインライン・ビューを持つ複雑なクエリーである場合もあります。マテリアライズド・ビューの問合せ定義にREFRESH FAST句が含まれる場合、TUNE_MVIEWによってそのクエリーが分析され、高速リフレッシュが可能かどうかが確認されます。すでに高速リフレッシュが可能な場合、「マテリアライズド・ビューはすでに最適であり、これ以上チューニングできません」というメッセージが戻されます。その他の場合、TUNE_MVIEWプロシージャによって特定の文に対してチューニング作業が開始されます。

TUNE_MVIEWプロシージャでは、FAST REFRESHが可能なように、必須集計列などの新しい列の追加やマテリアライズド・ビュー・ログの修正によって、問合せ定義を修正する出力文を生成できます。複雑な問合せ定義の場合、TUNE_MVIEWプロシージャでは、そのクエリーを分解して複数の高速リフレッシュ可能なマテリアライズド・ビューを生成するか、または高速リフレッシュの要件が最大限に満たされる方法でマテリアライズド・ビューを記述しなおすことがあります。TUNE_MVIEWプロシージャでは、次の複雑なクエリー構造を持つ問合せ定義がサポートされます。

ENABLE QUERY REWRITE句を指定した場合、TUNE_MVIEWでは、REFRESH FASTと同様のプロセスを使用して文が修正され、最大限の高度なクエリー・リライトが可能となるようにマテリアライズド・ビューが再定義されます。

TUNE_MVIEWプロシージャでは、実行可能文として、2つの出力結果が生成されます。1つの出力結果(IMPLEMENTATION)は、マテリアライズド・ビューと高速リフレッシュやクエリー・リライトを可能にするために必要なコンポーネント(マテリアライズド・ビュー・ログやリライト同値化)を最大限実装するためのものです。もう1つの出力結果(UNDO)は、不要と判断した場合にマテリアライズド・ビューとリライト同値化を削除するためのものです。

IMPLEMENTATIONプロセスの出力文には、次のものがあります。

分解により、サブマテリアライズド・ビューの共有ができなくなることがあります。つまり、分解を行うと、TUNE_MVIEWの出力には常に新しいサブマテリアライズド・ビューが含まれ、既存のマテリアライズド・ビューは参照されません。

UNDOプロセスの出力文には、次のものがあります。

UNDOプロセスには、マテリアライズド・ビュー・ログを削除する文は含まれません。これは、マテリアライズド・ビュー・ログが様々なマテリアライズド・ビューで共有されており、その一部はリモートのOracleインスタンスに存在する可能性があるためです。

TUNE_MVIEWの出力結果へのアクセス

TUNE_MVIEWの出力結果へのアクセス方法は2通りあります。

USER_TUNE_MVIEWビューおよびDBA_TUNE_MVIEWビュー

TUNE_MVIEWを実行すると、結果はSQLアクセス・アドバイザのリポジトリ表に出力され、OracleビューであるUSER_TUNE_MVIEWDBA_TUNE_MVIEWからアクセスできます。 詳細は、『Oracle Databaseリファレンス』を参照してください。

DBMS_ADVISOR関数およびプロシージャによるスクリプトの生成

推奨事項の実行スクリプトを生成する最も簡単な方法は、DBMS_ADVISOR.GET_TASK_SCRIPTプロシージャを使用することです。次に簡単な例を示します。まず、結果を格納するディレクトリを定義する必要があります。

CREATE DIRECTORY TUNE_RESULTS AS  '/tmp/script_dir';
GRANT READ, WRITE ON DIRECTORY TUNE_RESULTS TO PUBLIC;

次に、実装スクリプトとUNDOスクリプトを生成し、それぞれ/tmp/script_dir/mv_create.sql/tmp/script_dir/mv_undo.sqlに格納します。

EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT(:task_name),- 
      'TUNE_RESULTS', 'mv_create.sql'); 
EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT(:task_name, - 
      'UNDO'), 'TUNE_RESULTS', 'mv_undo.sql');

TUNE_MVIEWプロシージャの使用例を次にいくつか示します。

例 17-3    高速リフレッシュのための問合せ定義の最適化

この例では、TUNE_MVIEWによって問合せ定義を高速リフレッシュできるように変更する方法を示します。CREATE MATERIALIZED VIEW文は、変数create_mv_ddlで定義されています。これに、FAST REFRESH句が含まれています。問合せ定義に1つのクエリー・ブロックがあり、その集計列SUM(s.amount_sold)には高速リフレッシュをサポートするための必須集計列がありません。TUNE_MVIEW文をMATERIALIZED VIEW CREATE文とともに実行すると、その結果のマテリアライズド・ビューの推奨事項は高速リフレッシュ可能になります。

VARIABLE task_cust_mv VARCHAR2(30);
VARIABLE create_mv_ddl VARCHAR2(4000);
EXECUTE :task_cust_mv := 'cust_mv';

EXECUTE :create_mv_ddl := '
CREATE MATERIALIZED VIEW cust_mv
REFRESH FAST
DISABLE QUERY REWRITE AS
SELECT s.prod_id, s.cust_id, SUM(s.amount_sold) sum_amount
FROM sales s, customers cs
WHERE s.cust_id = cs.cust_id
GROUP BY s.prod_id, s.cust_id';

EXECUTE DBMS_ADVISOR.TUNE_MVIEW(:task_cust_mv, :create_mv_ddl);

cust_mvの元の問合せ定義は、高速リフレッシュを可能にするための集計列の追加によって変更されています。

TUNE_MVIEWからの出力には、次のように、最適化されたマテリアライズド・ビューの問合せ定義が含まれます。

CREATE MATERIALIZED VIEW SH.CUST_MV
REFRESH FAST WITH ROWID
DISABLE QUERY REWRITE AS
SELECT SH.SALES.PROD_ID C1, SH.CUSTOMERS.CUST_ID C2,
          SUM("SH"."SALES"."AMOUNT_SOLD") M1,
          COUNT("SH"."SALES"."AMOUNT_SOLD") M2,
          COUNT(*) M3
     FROM SH.SALES, SH.CUSTOMERS
     WHERE SH.CUSTOMERS.CUST_ID = SH.SALES.CUST_ID
     GROUP BY SH.SALES.PROD_ID, SH.CUSTOMERS.CUST_ID;

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

DROP MATERIALIZED VIEW SH.CUST_MV;

例 17-4    USER_TUNE_MVIEWビューからのIMPLEMENTATIONの出力へのアクセス

SELECT STATEMENT FROM USER_TUNE_MVIEW
WHERE TASK_NAME= :task_cust_mv AND SCRIPT_TYPE='IMPLEMENTATION';

例 17-5    スクリプト・ファイルへのIMPLEMENTATIONの出力の保存

CREATE DIRECTORY TUNE_RESULTS AS '/myscript'
GRANT READ, WRITE ON DIRECTORY TUNE_RESULTS TO PUBLIC;

EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT(:task_cust_mv), -
   'TUNE_RESULTS', 'mv_create.sql');

例 17-6    複数のマテリアライズド・ビューの作成によるクエリー・リライトの有効化

この例では、クエリー・リライトでサポートされない集合演算子UNIONを含むマテリアライズド・ビューの問合せ定義を、複数のサブマテリアライズド・ビューに分解し、クエリー・リライトを可能にする方法を示します。入力ディテール表として、salescustomersおよびcountriesを想定し、マテリアライズド・ビュー・ログはないものとします。

まず、TUNE_MVIEW文をcreate_mv_ddl変数で定義されているCREATE MATERIALIZED VIEW文とともに実行する必要があります。

EXECUTE :task_cust_mv := 'cust_mv2';

EXECUTE :create_mv_ddl := '
CREATE MATERIALIZED VIEW cust_mv
ENABLE QUERY REWRITE AS
SELECT s.prod_id, s.cust_id, COUNT(*) cnt, SUM(s.amount_sold) sum_amount
FROM sales s, customers cs, countries cn
WHERE s.cust_id = cs.cust_id AND cs.country_id = cn.country_id
AND cn.country_name IN (''USA'',''Canada'')
GROUP BY s.prod_id, s.cust_id
UNION
SELECT s.prod_id, s.cust_id, COUNT(*) cnt, SUM(s.amount_sold) sum_amount
FROM sales s, customers cs
WHERE s.cust_id = cs.cust_id AND s.cust_id IN (1005,1010,1012)
GROUP BY s.prod_id, s.cust_id';

マテリアライズド・ビューの問合せ定義には、通常のクエリー・リライトをサポートしないUNION集合演算子が含まれていますが、これを複数のマテリアライズド・ビューに分解すると、クエリー・リライトが可能になります。通常のクエリー・リライトをサポートするため、MATERIALIZED VIEW問合せ定義が分解されます。

EXECUTE DBMS_ADVISOR.TUNE_MVIEW(:task_cust_mv, :create_mv_ddl);

TUNE_MVIEWからの次の推奨事項は、マテリアライズド・ビュー・ログと複数のマテリアライズド・ビューで構成されています。

CREATE MATERIALIZED VIEW LOG ON "SH"."CUSTOMERS" 
WITH ROWID, SEQUENCE("CUST_ID")
    INCLUDING NEW VALUES;

ALTER MATERIALIZED VIEW LOG FORCE ON
    "SH"."CUSTOMERS"
    ADD ROWID, SEQUENCE("CUST_ID")
    INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW LOG ON
    "SH"."SALES"
    WITH ROWID, SEQUENCE("PROD_ID","CUST_ID","AMOUNT_SOLD")
    INCLUDING NEW VALUES;

ALTER MATERIALIZED VIEW LOG FORCE ON
    "SH"."SALES"
    ADD ROWID, SEQUENCE("PROD_ID","CUST_ID","AMOUNT_SOLD")
    INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW LOG ON
    "SH"."COUNTRIES"
    WITH ROWID, SEQUENCE("COUNTRY_ID","COUNTRY_NAME")
    INCLUDING NEW VALUES;

ALTER MATERIALIZED VIEW LOG FORCE ON
    "SH"."COUNTRIES"
    ADD ROWID, SEQUENCE("COUNTRY_ID","COUNTRY_NAME")
    INCLUDING NEW VALUES;

ALTER MATERIALIZED VIEW LOG FORCE ON
    "SH"."CUSTOMERS"
    ADD ROWID, SEQUENCE("CUST_ID","COUNTRY_ID")
    INCLUDING NEW VALUES;

ALTER MATERIALIZED VIEW LOG FORCE ON
    "SH"."SALES"
    ADD ROWID, SEQUENCE("PROD_ID","CUST_ID","AMOUNT_SOLD")
    INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW SH.CUST_MV$SUB1
    REFRESH FAST WITH ROWID ON COMMIT
    ENABLE QUERY REWRITE
    AS SELECT SH.SALES.PROD_ID C1, SH.CUSTOMERS.CUST_ID C2,
 SUM("SH"."SALES"."AMOUNT_SOLD")
        M1, COUNT("SH"."SALES"."AMOUNT_SOLD") M2, COUNT(*) M3 FROM SH.SALES,
        SH.CUSTOMERS WHERE SH.CUSTOMERS.CUST_ID = SH.SALES.CUST_ID AND
 (SH.SALES.CUST_ID IN (1012, 1010, 1005)) 
GROUP BY SH.SALES.PROD_ID, SH.CUSTOMERS.CUST_ID;

CREATE MATERIALIZED VIEW SH.CUST_MV$SUB2
    REFRESH FAST WITH ROWID ON COMMIT
    ENABLE QUERY REWRITE
    AS SELECT SH.SALES.PROD_ID C1, SH.CUSTOMERS.CUST_ID C2,
      SH.COUNTRIES.COUNTRY_NAME  C3, SUM("SH"."SALES"."AMOUNT_SOLD") M1, 
COUNT("SH"."SALES".
"AMOUNT_SOLD")
        M2, COUNT(*) M3 FROM SH.SALES, SH.CUSTOMERS, SH.COUNTRIES WHERE
 SH.CUSTOMERS.CUST_ID
        = SH.SALES.CUST_ID AND SH.COUNTRIES.COUNTRY_ID = SH.CUSTOMERS.COUNTRY_ID
        AND (SH.COUNTRIES.COUNTRY_NAME IN ('USA', 'Canada')) GROUP BY
 SH.SALES.PROD_ID,
        SH.CUSTOMERS.CUST_ID, SH.COUNTRIES.COUNTRY_NAME;

CREATE MATERIALIZED VIEW SH.CUST_MV
    REFRESH FORCE WITH ROWID
    ENABLE QUERY REWRITE
    AS  (SELECT "CUST_MV$SUB2"."C1" "PROD_ID","CUST_MV$SUB2"."C2" 
"CUST_ID",SUM("CUST_MV$SUB2"."M3")
        "CNT",SUM("CUST_MV$SUB2"."M1") "SUM_AMOUNT" FROM "SH"."CUST_MV$SUB2"
        "CUST_MV$SUB2" GROUP BY "CUST_MV$SUB2"."C1","CUST_MV$SUB2"."C2")UNION
        (SELECT "CUST_MV$SUB1"."C1" "PROD_ID","CUST_MV$SUB1"."C2" 
"CUST_ID",SUM("CUST_MV$SUB1"."M3")
        "CNT",SUM("CUST_MV$SUB1"."M1") "SUM_AMOUNT" FROM "SH"."CUST_MV$SUB1"
        "CUST_MV$SUB1" GROUP BY "CUST_MV$SUB1"."C1","CUST_MV$SUB1"."C2");

BEGIN
DBMS_ADVANCED_REWRITE.BUILD_SAFE_REWRITE_EQUIVALENCE ('SH.CUST_MV$RWEQ',
  'SELECT s.prod_id, s.cust_id, COUNT(*) cnt,
          SUM(s.amount_sold) sum_amount
   FROM sales s, customers cs, countries cn
   WHERE s.cust_id = cs.cust_id AND cs.country_id = cn.country_id
         AND cn.country_name IN (''USA'',''Canada'')
   GROUP BY s.prod_id, s.cust_id
   UNION
   SELECT s.prod_id, s.cust_id, COUNT(*) cnt,
          SUM(s.amount_sold) sum_amount
   FROM sales s, customers cs
   WHERE s.cust_id = cs.cust_id AND s.cust_id IN (1005,1010,1012)
   GROUP BY s.prod_id, s.cust_id',
  '(SELECT "CUST_MV$SUB2"."C3" "PROD_ID","CUST_MV$SUB2"."C2" "CUST_ID",
           SUM("CUST_MV$SUB2"."M3") "CNT",
           SUM("CUST_MV$SUB2"."M1") "SUM_AMOUNT" 
    FROM "SH"."CUST_MV$SUB2" "CUST_MV$SUB2"
    GROUP BY "CUST_MV$SUB2"."C3","CUST_MV$SUB2"."C2")
   UNION
   (SELECT "CUST_MV$SUB1"."C2" "PROD_ID","CUST_MV$SUB1"."C1" "CUST_ID",
           "CUST_MV$SUB1"."M3" "CNT","CUST_MV$SUB1"."M1" "SUM_AMOUNT"
    FROM "SH"."CUST_MV$SUB1" "CUST_MV$SUB1")',-1553577441)
END;
/;

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

DROP MATERIALIZED VIEW SH.CUST_MV$SUB1
DROP MATERIALIZED VIEW SH.CUST_MV$SUB2
DROP MATERIALIZED VIEW SH.CUST_MV
DBMS_ADVANCED_REWRITE.DROP_REWRITE_EQUIVALENCE('SH.CUST_MV$RWEQ')

cust_mvの元の問合せ定義は、cust_mv$SUB1およびcust_mv$SUB2という2つのサブマテリアライズド・ビューに分解されました。COUNT(amount_sold)という新しい列がcust_mv$SUB1に追加され、マテリアライズド・ビューの高速リフレッシュが可能になりました。

cust_mvの元の問合せ定義は、2つのサブマテリアライズド・ビューを問い合せるように変更され、両方のサブマテリアライズド・ビューで高速リフレッシュと通常のクエリー・リライトが可能です。

必要なマテリアライズド・ビュー・ログが追加され、サブマテリアライズド・ビューの高速リフレッシュが可能です。ディテール表ごとに、2つのマテリアライズド・ビュー・ログ文が生成されます。1つはCREATE MATERIALIZED VIEW文、もう1つはALTER MATERIALIZED VIEW FORCE文です。これは、CREATEスクリプトを複数回実行できるようにするためです。

BUILD_SAFE_REWRITE_EQUIVALENCE文は、古い問合せ定義を、新しいトップレベルのマテリアライズド・ビューの問合せ定義に結合します。これによって、クエリー・リライトで新しいトップレベルのマテリアライズド・ビューを使用して問合せに応答できるようにします。

例 17-7    USER_TUNE_MVIEWビューからのIMPLEMENTATIONの出力へのアクセス

SELECT * FROM USER_TUNE_MVIEW
WHERE TASK_NAME='cust_mv2'
AND SCRIPT_TYPE='IMPLEMENTATION';

例 17-8    スクリプト・ファイルへのIMPLEMENTATIONの出力の保存

次の文では、IMPLEMENTATIONの出力が、/myscript/mv_create2.sqlにあるスクリプト・ファイルに保存されます。

CREATE DIRECTORY TUNE_RESULTS AS '/myscript'
GRANT READ, WRITE ON DIRECTRY TUNE_RESULTS TO PUBLIC;
EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT('cust_mv2'),
   'TUNE_RESULTS', 'mv_create2.sql');

最適化されたサブマテリアライズド・ビューによる高速リフレッシュの有効化

この例では、TUNE_MVIEWを使用して、高速リフレッシュを行えるようにマテリアライズド・ビューを最適化する方法を示します。この例では、集合演算子を持つマテリアライズド・ビューの問合せ定義が1つのサブマテリアライズド・ビューと1つのトップレベル・マテリアライズド・ビューに変換されます。元の問合せ定義の副問合せの形式は類似しており、条件式は結合されます。

マテリアライズド・ビュー自体が高速リフレッシュできないよう、マテリアライズド・ビューの問合せ定義にはUNION集合演算子が含まれています。ただし、マテリアライズド・ビューの問合せ定義内の2つの副問合せを、1つの問合せとして結合できます。

例 17-9    高速リフレッシュのためのサブマテリアライズド・ビューの最適化

EXECUTE :task_cust_mv := 'cust_mv3';
EXECUTE :create_mv_ddl := '

CREATE MATERIALIZED VIEW cust_mv
REFRESH FAST ON DEMAND
ENABLE QUERY REWRITE AS
SELECT s.prod_id, s.cust_id, COUNT(*) cnt, SUM(s.amount_sold) sum_amount
FROM sales s, customers cs
WHERE s.cust_id = cs.cust_id AND s.cust_id IN (2005,1020)
GROUP BY s.prod_id, s.cust_id UNION
SELECT s.prod_id, s.cust_id, COUNT(*) cnt, SUM(s.amount_sold) sum_amount
FROM sales s, customers cs -
WHERE s.cust_id = cs.cust_id AND s.cust_id IN (1005,1010,1012)
GROUP BY s.prod_id, s.cust_id';

EXECUTE DBMS_ADVISOR.TUNE_MVIEW(:task_cust_mv, :create_mv_ddl);

TUNE_MVIEWと2つの副問合せを結合して最適化されたサブマテリアライズド・ビューで次の推奨事項が生成され、サブマテリアライズド・ビューは新しいトップレベルのマテリアライズド・ビューによって参照されます。

CREATE MATERIALIZED VIEW LOG ON "SH"."SALES" 
  WITH ROWID, SEQUENCE ("PROD_ID","CUST_ID","AMOUNT_SOLD")
  INCLUDING NEW VALUES

ALTER MATERIALIZED VIEW LOG FORCE ON "SH"."SALES"
  ADD ROWID, SEQUENCE ("PROD_ID","CUST_ID","AMOUNT_SOLD")
  INCLUDING NEW VALUES

CREATE MATERIALIZED VIEW LOG ON "SH"."CUSTOMERS" 
  WITH ROWID, SEQUENCE ("CUST_ID")  INCLUDING NEW VALUES

ALTER MATERIALIZED VIEW LOG FORCE ON "SH"."CUSTOMERS"
  ADD ROWID, SEQUENCE ("CUST_ID")  INCLUDING NEW VALUES

CREATE MATERIALIZED VIEW SH.CUST_MV$SUB1
  REFRESH FAST WITH ROWID
  ENABLE QUERY REWRITE AS
  SELECT SH.SALES.CUST_ID C1, SH.SALES.PROD_ID C2, 
    SUM("SH"."SALES"."AMOUNT_SOLD") M1, 
    COUNT("SH"."SALES"."AMOUNT_SOLD")M2, COUNT(*) M3 
    FROM SH.CUSTOMERS, SH.SALES
    WHERE SH.SALES.CUST_ID = SH.CUSTOMERS.CUST_ID AND
    (SH.SALES.CUST_ID IN (2005, 1020, 1012, 1010, 1005))
    GROUP BY SH.SALES.CUST_ID, SH.SALES.PROD_ID

CREATE MATERIALIZED VIEW SH.CUST_MV 
  REFRESH FORCE WITH ROWID ENABLE QUERY REWRITE AS
  (SELECT "CUST_MV$SUB1"."C2" "PROD_ID","CUST_MV$SUB1"."C1" "CUST_ID",
    "CUST_MV$SUB1"."M3" "CNT","CUST_MV$SUB1"."M1" "SUM_AMOUNT" 
    FROM "SH"."CUST_MV$SUB1" "CUST_MV$SUB1" 
    WHERE "CUST_MV$SUB1"."C1"=2005 OR "CUST_MV$SUB1"."C1"=1020)
    UNION 
    (SELECT "CUST_MV$SUB1"."C2" "PROD_ID","CUST_MV$SUB1"."C1" "CUST_ID",
      "CUST_MV$SUB1"."M3" "CNT","CUST_MV$SUB1"."M1" "SUM_AMOUNT" 
      FROM "SH"."CUST_MV$SUB1" "CUST_MV$SUB1" 
      WHERE "CUST_MV$SUB1"."C1"=1012 OR "CUST_MV$SUB1"."C1"=1010 OR 
            "CUST_MV$SUB1"."C1"=1005)
      
DBMS_ADVANCED_REWRITE.BUILD_SAFE_REWRITE_EQUIVALENCE ('SH.CUST_MV$RWEQ',
      'SELECT s.prod_id, s.cust_id, COUNT(*) cnt, 
       SUM(s.amount_sold) sum_amount
       FROM sales s, customers cs
       WHERE s.cust_id = cs.cust_id AND s.cust_id IN (2005,1020)
       GROUP BY s.prod_id, s.cust_id UNION
       SELECT s.prod_id, s.cust_id, COUNT(*) cnt,
       SUM(s.amount_sold) sum_amount
       FROM sales s, customers cs
       WHERE s.cust_id = cs.cust_id AND s.cust_id IN (1005,1010,1012)
       GROUP BY s.prod_id, s.cust_id',
      '(SELECT "CUST_MV$SUB1"."C2" "PROD_ID",
        "CUST_MV$SUB1"."C1" "CUST_ID",
        "CUST_MV$SUB1"."M3" "CNT","CUST_MV$SUB1"."M1" "SUM_AMOUNT" 
        FROM "SH"."CUST_MV$SUB1" "CUST_MV$SUB1" 
        WHERE "CUST_MV$SUB1"."C1"=2005OR "CUST_MV$SUB1"."C1"=1020)
       UNION
       (SELECT "CUST_MV$SUB1"."C2" "PROD_ID",
        "CUST_MV$SUB1"."C1" "CUST_ID",
        "CUST_MV$SUB1"."M3" "CNT","CUST_MV$SUB1"."M1" "SUM_AMOUNT"
        FROM "SH"."CUST_MV$SUB1" "CUST_MV$SUB1" 
        WHERE "CUST_MV$SUB1"."C1"=1012 OR "CUST_MV$SUB1"."C1"=1010 OR
              "CUST_MV$SUB1"."C1"=1005)',
      1811223110);

cust_mvの元の問合せ定義は、サブマテリアライズド・ビューCUST_MV$SUB1の2つの副問合せの条件を結合することで最適化されています。また、必要なマテリアライズド・ビュー・ログも追加され、サブマテリアライズド・ビューの高速リフレッシュが可能です。

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

DROP MATERIALIZED VIEW SH.CUST_MV$SUB1
DROP MATERIALIZED VIEW SH.CUST_MV
DBMS_ADVANCED_REWRITE.DROP_REWRITE_EQUIVALENCE('SH.CUST_MV$RWEQ');

次の文では、IMPLEMENTATIONの出力が、/myscript/mv_create3.sqlにあるスクリプト・ファイルに保存されます。

CREATE DIRECTORY TUNE_RESULTS AS '/myscript'
GRANT READ, WRITE ON DIRECTORY TUNE_RESULTS TO PUBLIC;
EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT('cust_mv3'),
   'TUNE_RESULTS', 'mv_create3.sql');

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

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