このチュートリアルでは、Oracle Database 11gのSQL実行計画の管理方法について説明します。
約30分
このチュートリアルでは、以下について説明します。
| 概要 | ||
| 前提条件 | ||
| 計画の自動取得 | ||
| 計画の一括取得 | ||
| 計画の管理 | ||
| まとめ | ||
このアイコンの上にカーソルを置くと、すべてのスクリーンショットがロードし、表示されます。(警告:すべてのスクリーンショットが同時にロードされるため、ご使用のインターネット接続によってはレスポンス・タイムが遅くなる場合があります。)
注:各手順に関連したスクリーンショットのみを表示する場合は、それぞれの手順にあるアイコンの上にカーソルを置いてください。スクリーンショットをクリックすると、非表示になります。
SQL文の実行計画が変更される場合、パフォーマンスのリスクが発生する可能性があります。 システムで発生する変更(オプティマイザ・バージョン、オプティマイザ統計、オプティマイザ・パラメータ、スキーマ/メタデータ定義、システム設定、SQLプロファイル作成など)を含むさまざまな理由によって、計画が変更されることがあります。システム変更(索引の削除など)によって、元に戻せない計画の変更が発生する場合もあります。計画の変更が良い方向に向かうとは限らないため、実行計画またはオプティマイザ統計を固定する顧客もいます。
Oracle Database 11gでは、実行計画の展開を制御する新機能のSQL Plan Management(SPM)が導入されています。SPMを使用すると、オプティマイザは、実行計画を自動的に管理し、既知の計画または検証された計画だけの使用を保証します。SQL文に新しい計画が存在する場合、現在の計画と同等またはそれ以上のパフォーマンスを確認するまで、その計画は使用されません。
このチュートリアルを始める前に、次の手順を完了している必要があります。
| 1. | Oracle Database 11gがインストールされていること。 |
|
| 2. | 作業ディレクトリへのspm.zipファイルのダウンロードおよび解凍が済んでいること。 |
|
init.oraパラメータのoptimizer_capture_sql_plan_baselinesをtrueに設定すると、計画の自動取得を有効にできます。計画の自動取得が有効な場合、繰り返し可能なSQL文がSPMリポジトリに自動的に移入されます。繰り返し可能なSQL文を識別するため、オプティマイザは、最初にコンパイルする際に各SQL文のIDをステートメント・ログに格納します。 SQL文のIDが記録された後、再処理(実行またはコンパイル)が行われる場合、ステートメント・ログのIDは、繰り返し可能な文であることを示しています。SQL計画履歴が作成され、現在の計画またはコスト・ベースの計画が最初の計画ベースラインとして追加されます。以下の手順を実行します。
| 1. | Oracle Enterprise Manager Database Controlを開いて、systemユーザーとしてログインします。
|
| 2. | 「Server」タブを選択します。
|
| 3. | Query Optimizerの下の「SQL Plan Control」を選択します。
|
| 4. | 「SQL Plan Baseline」タブを選択します。
|
| 5. | Settingsの下のCapture SQL Plan Baselinesの「FALSE」リンクを選択します。
|
| 6. | optimizer_capture_sql_plan_baselineパラメータの値にTRUEを選択し、「OK」をクリックします。
|
| 7. | パラメータがTRUEに設定されました。
|
| 8. | SQL*Plusセッションを開いて、SYSTEMとしてログインします。最初のSQL文の実行なので繰り返し可能な文ではありません。また、計画ベースラインもまだありません。このため、次の問合せを2回実行する必要があります。 @load_auto_select.sql
|
| 9. | Oracle Enterprise Managerに切り替え、SQL Textフィールドに%LOAD_AUTO%と入力して、「Go」をクリックします。
|
| 10. | 計画がリストに表示されます。SQL Textのリンクを選択して、詳細を参照します。
|
| 11. | SQL計画ベースラインの詳細が表示されます。ベースラインが自動的にロードされたため、OriginにAUTO_CAPTUREが設定されます。「Return」をクリックします。
|
| 12. | オプティマイザ・モードを変更して、SQL文を異なる計画で実行します。SQL*Plusに切り替えて、オプティマイザ・モードを変更します。次のコマンドを実行します。 alter session set optimizer_mode = first_rows;
|
| 13. | 次の問合せを再実行します。 @load_auto_select.sql
|
| 14. | SQL文に新しい計画が使用されるので、別の計画ベースラインが自動的に取得されます。SQL Plan Baselineで、このことを確認できます。Oracle Enterprise Manager Database Controlに戻って、「Go」をクリックします。
|
| 15. | SQL問合せの2つの計画ベースラインが表示されますが、2つ目の計画がまだ承認されていません。適切な計画として承認する前に、この新しい計画を検証する必要があります。承認されていない計画のチェック・ボックスを選択し、「Evolve」をクリックします。
|
| 16. | この場合、この新しい計画が現在のSQL計画ベースラインと同等またはそれ以上のパフォーマンスかどうかは関係なく、Verify PerformanceのNoを選択することになります。これはこの計画が、パフォーマンスに関係なく、承認されたSQL計画ベースラインになるということです。 「OK」をクリックして計画を展開し、後続の確認ウィンドウで「Return」をクリックします。
|
| 17. | SQL Plan Controlウィンドウに戻り、もう一度「Go」をクリックしてリストをリフレッシュします。
|
| 18. | 計画が承認されました。EXPLAIN PLANを確認するには、SQL Textのリンクを選択します。
|
| 19. | この計画は、ビットマップ索引の全体スキャンを実行します。「Return」をクリックします。
|
| 20. | オプティマイザ・モードをデフォルト値に再設定して、計画ベースラインの自動取得を無効にできます。SQL*Plusセッションに切り替えて、以下のコマンドを実行します。 alter session set optimizer_mode = all_rows;
|
| 21. | Oracle Enterprise Manager Database Controlに戻ります。Capture SQL PLAN Baselinesの「TRUE」リンクを選択します。
|
| 22. | optimizer_capture_sql_plan_baselineパラメータの値にFALSEを選択し、「OK」をクリックします。
|
| 23. | パラメータが変更されました。
|
| 24. | SQLベースラインを削除できます。各ベースラインのチェック・ボックスを選択し、「Drop」をクリックします。
|
| 25. | 「Yes」をクリックして、削除を確定します。
|
| 26. | ベースラインが削除されました。
|
計画の一括取得には、2つの方法があります。
| |
|
| カーソル・キャッシュから |
SQL Tuning Setを使用して、重要なSQL文の計画の詳細を取得できます。Oracle Databaseを10gから11gにアップグレードする場合、これは、必要のない計画変更を防止する方法の1つです。以下の手順を実行します。
| 1. | 実行する必要がある最初のタスクは、EXPLAIN PLANの確認です。SQL*Plusセッションに切り替えて、以下のスクリプトを実行します。 @load_sts_explain_plan
|
| 2. | 次に、以下のスクリプトを使用して、SQL文を実行します。 @load_sts_select
|
| 3. |
以下のコマンドを実行して、オプティマイザ・モードを変更できます。 alter session set optimizer_mode = first_rows;
|
| 4. | 以下のスクリプトを再実行して、異なる計画を取得します。 @load_sts_explain_plan
|
| 5. |
次に、以下のコマンドを実行して、オプティマイザ・モードを再設定します。 alter session set optimizer_mode = all_rows;
|
| 6. | この時点で、SQL Tuning Setを作成し、計画をロードできます。SQL*Plusセッションで以下のスクリプトを実行して、SQL Tuning Setを作成します。 @cr_sts
|
| 7. |
実行したSQLにSQL Tuning Setを移入できます。以下のスクリプトを実行して、SQL Tuning Setを移入します。 @populate_sts
|
| 8. | Oracle Enterprise Managerに切り替えます。作成したSQL Tuning Setに基づいて、計画をロードできます。「SQL Plan Control」→「SQL Plan Baseline」タブを選択し、「Load」をクリックします。
|
| 9. | SQL Tuning Setの懐中電灯を選択します。
|
| 10. | SQL Tuning SetのSPM_STSを選択し、「Select」をクリックします。
|
| 11. | 「OK」をクリックして、ベースライン・ジョブを作成します。
|
| 12. | ベースラインが作成されます。「Refresh」をクリックします。
|
| 13. | SQL Textフィールドに%LOAD_STS%と入力し、「Go」をクリックします。
|
| 14. | SQL Textのリンクを選択します。
|
15 . |
EXPLAIN PLANが表示されます。今回は、計画が作成されたのでOriginにMANUAL-LOADが設定されます。「Return」をクリックします。
|
| 16. | SQLベースラインを削除できます。各ベースラインのチェック・ボックスを選択し、「Drop」をクリックします。
|
| 17. | 「Yes」をクリックして、削除を確定します。
|
| 18. | ベースラインが削除されました。
|
dbms_spm.load_plans_from_cursor_cacheを使用して、カーソル・キャッシュから直接計画をロードできます。カーソル・キャッシュのすべての文の計画をロードできます。また、モジュール名やスキーマ名などにフィルタを適用できます。これらの文が次に実行される場合、ベースライン計画が使用されます。以下の手順を実行します。
| 1. | 実行する必要がある最初のタスクは、EXPLAIN PLANの確認です。SQL*Plusセッションに切り替えて、以下のスクリプトを実行します。 @load_cc_explain_plan
|
| 2. | 次に、以下のスクリプトを使用して、SQL文を実行します。 @load_cc_select
|
| 3. | 以下のコマンドを実行して、オプティマイザ・モードを変更できます。 alter session set optimizer_mode = first_rows;
|
| 4. | 以下のスクリプトを再実行して、異なる計画を取得します。 @load_cc_explain_plan
|
| 5. | 次に、以下のコマンドを実行して、オプティマイザ・モードを再設定します。 alter session set optimizer_mode = all_rows;
|
| 6. | カーソル・キャッシュに移入された後、SQL文のSQL IDを取得する必要があります。これは、ベースラインをロードする場合にカーソル・キャッシュの内容をフィルタリングするために使用されます。以下のスクリプトを実行します。 @load_cc_get_sql_id
|
| 7. | 計画をロードし、ベースラインを作成できます。Oracle Enterprise Manager Database Controlに切り替えます。「Server」→「SQL Plan Control」→「SQL Plan Baseline」ページを選択し、「Load」をクリックします。
|
| 8. | 「Load plans from cursor cache」ラジオ・ボタンを選択し、SQL IDの懐中電灯を選択します。
|
| 9. | SQL Textに%LOAD_CC%と入力し、「Go」をクリックします。
|
| 10. | SQL*Plusでカーソル・キャッシュに問合せた際に以前の手順で確認したSQL IDのチェック・ボックスを選択し、「Select」をクリックします。
|
| 11. | 「OK」をクリックします。
|
| 12. | ジョブが送信されました。SQL Textに%LOAD_CC%と入力し、「Go」をクリックします。
|
| 13. | SQL文のリンクを選択します。
|
| 14. | EXPLAIN PLANが表示されます。「Return」をクリックします。
|
| 15. | SQLベースラインを削除できます。各ベースラインのチェック・ボックスを選択し、「Drop」をクリックします。
|
| 16. | 「Yes」をクリックして、削除を確定します。
|
| 17. | ベースラインが削除されました。
|
SQL文がコンパイルされるたびに、オプティマイザは、従来のコスト・ベースの検索方法を使用して、最適なコスト計画を構築します。初期化パラメータのOPTIMIZER_USE_PLAN_BASELINESがTRUE(デフォルト値)に設定されていると、SQL計画ベースラインのパッチ計画が検索されます。一致すると、通常の処理が続行されます。一致しない場合、計画履歴に新しい計画が追加され、SQL計画ベースラインの承認された計画にそれぞれコストがかかるため、最小コストの計画を選択します。以下の手順を実行します。
| 1. | 実行する必要がある最初のタスクは、EXPLAIN PLANの確認です。SQL*Plusセッションに切り替えて、以下のスクリプトを実行します。 @use_opm_explain_plan
|
| 2. | 次に、以下のスクリプトを使用して、SQL文を実行します。 @use_opm_select
|
| 3. | 以下のコマンドを実行して、オプティマイザ・モードを変更できます。 alter session set optimizer_mode = first_rows;
|
| 4. | 以下のスクリプトを再実行して、異なる計画を取得します。 @use_opm_explain_plan
|
| 5. | 次に、以下のコマンドを実行して、オプティマイザ・モードを再設定します。 alter session set optimizer_mode = all_rows;
|
| 6. | カーソル・キャッシュに移入された後、SQL文のSQL IDを取得する必要があります。これは、ベースラインをロードする場合にカーソル・キャッシュの内容をフィルタリングするために使用されます。以下のスクリプトを実行します。 @use_opm_get_sql_id
|
| 7. | 計画をロードし、ベースラインを作成できます。Oracle Enterprise Manager Database Controlに切り替えます。「Server」→「SQL Plan Control」→「SQL Plan Baseline」ページを選択し、「Load」をクリックします。
|
| 8. | 「Load plans from cursor cache」ラジオ・ボタンを選択し、SQL IDの懐中電灯を選択します。
|
| 9. | SQL Textに%USE_OPM%と入力し、「Go」をクリックします。
|
| 10. | SQL*Plusでカーソル・キャッシュに問合せた際に以前の手順で確認したSQL IDのチェック・ボックスを選択し、「Select」をクリックします。
|
| 11. | 「OK」をクリックします。
|
| 12. | ジョブが実行されました。 SQL Text検索フィールドに%USE_OPM%と入力し、「Go」をクリックします。SQL計画ベースラインが表示されます。
|
| 13. | 計画がロードされるので、計画が使用されていることを確認します。SQL*Plusセッションに切り替えて、以下のスクリプトを実行します。 @use_opm_explain_plan2
出力の最後のNoteは、ベースラインが使用されていることを示しています。実行計画から、最初のベースライン(全表スキャン)が使用されていることがわかります。
|
| 14. | オプティマイザ・モードをfirst_rowsに戻すと、他のベースラインに変更できます。次のコマンドを実行します。 alter session set optimizer_mode = first_rows;
|
| 15. | EXPLAIN PLANを再実行して、他のベースラインを確認します。以下のスクリプトを実行します。 @use_opm_explain_plan2
実行計画から、2つ目のベースライン(ビットマップ索引の全体スキャン)が使用されていることがわかります。
|
| 16. | この時点で、計画ベースラインを無効にします。また、他の計画ベースラインの使用を確認します。Oracle Enterprise Managerに切り替えて、以前の手順でEXPLAIN PLANに表示された計画のチェック・ボックスを選択します。「Disable」をクリックします。
|
| 17. | 計画が無効になりました。
|
| 18. | SQL*Plusセッションに切り替えて、以下のスクリプトを再実行します。 @use_opm_explain_plan2
実行計画から、使用されている計画が全表スキャンではなく索引スキャンであることを確認できます。これは、2つ目のベースラインです。
|
| 19. | 実行する最後のタスクは、他の計画ベースラインの無効化です。オプティマイザは、コスト・ベースの方法を使用します。Oracle Enterprise Managerに切り替えて、以前の手順でEXPLAIN PLANに表示された計画のチェック・ボックスを選択します。「Disable」をクリックします。
|
| 20. | 両方の計画が無効になりました。
|
| 21. | SQL*Plusセッションに切り替えて、以下のスクリプトを最後にもう一度実行します。 @use_opm_explain_plan2
ベースラインの使用を示すNoteが最後に表示されていないので、オプティマイザは、デフォルトのコスト・ベースの方法を使用しています。
|
| 22. | SQLベースラインを削除できます。各ベースラインのチェック・ボックスを選択し、「Drop」をクリックします。
|
| 23. | 「Yes」をクリックして、削除を確定します。
|
| 24. | ベースラインが削除されました。
|
このチュートリアルで学習した内容は、次のとおりです。
| 計画の自動取得 | ||
| SQL Tuning SetまたはSQL IDを使用した計画の取得 | ||
| 使用する計画の選択 | ||
このアイコンの上にカーソルを置くと、すべてのスクリーンショットが非表示になります。