28 SQL計画管理の概要
SQL計画管理は、データベースで既知の計画または確認済の計画のみが使用されるようにオプティマイザで実行計画を自動的に管理する予防的なメカニズムです。
28.1 SQL計画ベースラインについて
SQL計画管理では、オプティマイザがSQL文に使用できる承認済の計画のセットであるSQL計画ベースラインというメカニズムが使用されます。
このコンテキストで、計画には、オプティマイザで実行計画を再現するために必要な計画に関連するすべての情報(たとえば、SQL計画識別子、一連のヒント、バインド値、オプティマイザ環境など)が含まれます。このベースラインは、計画行のセットおよび計画の再現に必要なアウトラインとして実装されます。アウトラインは、特定の計画を強制適用するために使用されるオプティマイザ・ヒントのセットです。
SQL計画管理の主要コンポーネントは次のとおりです。
-
計画の取得
このコンポーネントは、一連のSQL文に対する計画に関連する情報を保存します。
-
計画の選択
このコンポーネントは、保存された計画履歴に基づいたオプティマイザによる計画変更の検出、およびパフォーマンスが低下する可能性を回避するための適切な計画の選択でのSQL計画ベースラインの使用です。
-
計画の展開
このコンポーネントは、手動または自動での、既存のSQL計画ベースラインへの新規計画の追加プロセスです。通常のユースケースの場合、データベースで計画の正常な実行が検証された後のみ、計画が計画ベースラインに承認されます。
28.2 SQL計画管理の目的
SQL計画管理では、計画の変更によって発生するパフォーマンスの低下を防止します。
2つ目の目的は、計画変更を検証し、パフォーマンスを改善させる計画変更のみを承認することにより、新しいオプティマイザ統計や索引などの変更にスムーズに適応することです。
ノート:
SQL計画ベースラインでは、索引の削除などによる元に戻せない実行計画の変更を防止することはできません。
28.2.1 SQL計画管理の利点
SQL計画の管理により、データベース・アップグレードおよびシステムとデータの変更でSQLパフォーマンスを向上または維持できます。
特に、次の利点が得られます。
-
新しいバージョンのオプティマイザをインストールするデータベースのアップグレードでは、通常、ほんのわずかなSQL文に対して計画の変更が発生します。
ほとんどの計画変更において、パフォーマンスの向上が見られるか、または変化がありません。ただし、一部の計画の変更は、パフォーマンスの低下の原因となることがあります。SQL計画ベースラインにより、アップグレードがもたらす低下の可能性を最小限に抑えられます。
アップグレード時には、データベースにより計画ベースラインからの計画のみが使用されます。データベースは現在のベースラインに含まれない新しい計画を保持領域に入れ、後でそれらを評価し、ベースラインに含まれる現在の計画よりも少ないリソースを使用するかどうかを判断します。それらの計画のパフォーマンスがより優れている場合は、それらの計画をベースラインに昇格させます。そうでない場合は昇格させません。
-
継続的なシステムおよびデータの変更は、一部のSQL文の計画に影響を及ぼし、パフォーマンスの低下を招く可能性があります。
SQL計画ベースラインにより、パフォーマンスの低下を最小限に抑えて安定したSQLパフォーマンスを維持できます。
-
新しいアプリケーション・モジュールのデプロイメントは、新しいSQL文をデータベースに導入します。
アプリケーション・ソフトウェアは、新しい文に対して標準のテスト構成で作成された適切なSQL実行計画を使用できます。システム構成がテスト構成と大幅に異なる場合、データベースはSQL計画ベースラインを時間の経過とともに進化させてパフォーマンスを改善します。
関連項目:
Oracleデータベースのアップグレード方法を学習するには、『Oracle Databaseアップグレード・ガイド』を参照してください。
28.2.2 SQL計画ベースラインとSQLプロファイルの違い
SQLプロファイルとSQL計画ベースラインのどちらも、オプティマイザで最適な計画のみが使用されるようにすることによりSQL文のパフォーマンスを向上させます。
プロファイルとベースラインはどちらも、ヒントを使用して内部的に実装されます。ただし、これらのメカニズムには次を含めて大きな違いがあります。
-
一般的に、SQL計画ベースラインは事前対応型であるのに対し、SQLプロファイルは事後対応型です。
通常、SQL計画ベースラインは重大なパフォーマンスの問題が発生する前に作成します。SQL計画ベースラインは、オプティマイザが最適ではない計画を将来的に使用することを防ぎます。
SQLプロファイルは、SQLチューニング・アドバイザを起動するとデータベースにより作成されます。通常、チューニング・アドバイザは、SQL文により高負荷の兆候が示された後にのみ起動します。SQLプロファイルは主に、最適ではない計画につながったオプティマイザのミスを継続的に解決するために使用できます。SQLプロファイル・メカニズムは事後対応であるため、データベースに重大な変更が生じた場合は安定したパフォーマンスを保証できません。
-
SQL計画ベースラインは特定の計画を再現するのに対し、SQLプロファイルはオプティマイザのコスト見積りを修正します。
SQL計画ベースラインは一連の承認済計画から構成されます。各計画は、特定の計画を完全に指定するアウトライン・ヒントのセットを使用して実装されます。SQLプロファイルもヒントを使用して実装されますが、これらのヒントでは特定の計画は指定されません。これらのヒントは、最適ではない計画につながったオプティマイザの見積りの計算ミスを修正します。たとえば、ヒントにより表のカーディナリティ予測が修正されます。
プロファイルによりオプティマイザは特定の1つの計画に制限されないため、SQLプロファイルはSQL計画ベースラインよりも柔軟です。たとえば、初期化パラメータやオプティマイザ統計の変更により、オプティマイザはより最適な計画を選択できます。
SQLチューニング・アドバイザを使用することをお薦めします。これにより、SQLプロファイルと計画ベースラインのどちらが各SQL文に最適なメカニズムであるのかを自分で判断せずに、アドバイザの推奨事項に従うことができます。
28.3 計画の取得
SQL計画の取得とは、一連のSQL文に対して、計画に関連する情報を取得し、SQL管理ベースに保存するための方法を指します。
計画の取得とは、SQL計画管理にこの計画を認識させることを意味します。初期化パラメータを設定することにより初期計画の取得が自動的に発生するように構成するか、DBMS_SPM
パッケージを使用して計画を手動で取得できます。
28.3.1 初期計画の自動取得
有効時には、データベースは実行されたSQL文の自動取得が可能であるかどうかを確認します。
初期計画の自動取得は、OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES
をtrue
に設定にすることで有効化できます(デフォルトはfalse
)。初期化パラメータのOPTIMIZER_USE_SQL_PLAN_BASELINES
は無関係であることに注意してください。たとえば、OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES
がtrue
の場合、OPTIMIZER_USE_SQL_PLAN_BASELINES
の設定がtrue
とfalse
のいずれでも、初期計画ベースラインが作成されます。
関連項目:
-
"計画の選択"
-
OPTIMIZER_USE_SQL_PLAN_BASELINES
初期化パラメータについて学習するには、『Oracle Databaseリファレンス』を参照してください
28.3.1.1 初期計画の自動取得の対象
計画の自動取得の対象になるには、実行された文が繰返し可能であることと、どの取得フィルタでも除外されていないことが必要です。
デフォルトでは、データベースは、すべての繰返し可能なSQL文を取得の対象とみなします。ただし、次の例外があります。
-
AS SELECT
句が指定されていない場合のCREATE TABLE
-
DROP TABLE
-
INSERT INTO ... VALUES
対象になるかどうかの最初のチェックは、繰り返される実行です。実行が2回未満の文については、データベースはSQL計画ベースラインの対象と見なしません。2回以上実行される文については、定義によって繰返し可能になるため、データベースは詳細なチェックの対象と見なします。
ノート:
SQL計画管理では、EXPLAIN PLAN
を使用して説明されていても、まだ実行されていない文は保護しません。
繰返し可能な文に対して、DBMS_SPM.CONFIGURE
プロシージャにより自動取得フィルタを作成できます。これにより、必要な文のみを取得して重要でない文を除外できるため、SYSAUX
表領域の領域が削減されます。多くの場合、重要でない問合せには、次の特性があります。
-
重要でないと頻繁に実行されません
-
リソース集中型ではありません
-
SQL計画管理から利点を得るのは、それほど複雑ではありません
指定されたパラメータに対して、フィルタでは、指定した値の文の計画が含まれるか(enable=>TRUE
)、除外されます(enable=>FALSE
)。取得の対象とするには、繰返し可能な文をフィルタで除外しないでください。DBMS_SPM.CONFIGURE
プロシージャは、SQLテキストのフィルタをサポートし、スキーマ名、モジュールおよびアクションを解析します。
パラメータのnull値により、フィルタが削除されます。allow=FALSE
と組み合せてparameter_value=>'%'
を使用することで、パラメータのすべての値をフィルタ処理で除外し、個別のフィルタを作成して指定された値のみを含めることができます。DBA_SQL_MANAGEMENT_CONFIG
ビューには、現在のフィルタが示されます。
関連項目:
-
DBMS_SPM.CONFIGURE
プロシージャについてさらに学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。 -
DBA_SQL_MANAGEMENT_CONFIG
ビューについてさらに学習するには、『Oracle Databaseリファレンス』を参照してください
28.3.1.2 初期計画の自動取得の計画照合
データベースが繰返し可能なSQL文を実行し、この文がDBMS_SPM.CONFIGURE
フィルタを通過する場合、データベースはSQL計画ベースラインの計画との照合を試行します。
初期計画の自動取得の場合、計画照合アルゴリズムは、次のとおりです。
-
SQL計画ベースラインが存在しない場合、オプティマイザによって文に対する計画履歴およびSQL計画ベースラインが作成され、その文に対する最初の計画が承認済としてマークされ、SQL計画ベースラインに追加されます。
-
SQL計画ベースラインが存在する場合、オプティマイザの動作は、解析時に導出されたコストベースの計画によって決まります。
-
この計画がSQL計画ベースラインと一致しない場合、オプティマイザは新しい計画を未承認とマークし、SQL計画ベースラインに追加します。
-
この計画がSQL計画ベースラインと一致する場合、SQL計画ベースラインには何も追加されません。
-
28.3.2 計画の手動取得
SQL計画管理では、計画の手動取得とは、ユーザーによるSQL計画ベースラインへの既存計画の一括ロードを指します。
SQL文に対する実行計画をAWR、SQLチューニング・セット(STS)、共有SQL領域、ステージング表またはストアド・アウトラインからロードするには、Cloud ControlまたはPL/SQLを使用します。
ロード動作は、一括ロードに含まれる各文に対してSQL計画ベースラインが存在するかどうかによって異なります。
-
文に対するベースラインが存在しない場合、データベースは次の処理を行います。
-
文に対する計画履歴と計画ベースラインを作成します。
-
文に対する最初の計画を承認済とマークします。
-
計画を新しいベースラインに追加します。
-
-
文に対するベースラインが存在する場合、データベースは次の処理を行います。
-
ロードした計画を承認済とマークします。
-
計画のパフォーマンスを検証せずに、計画を文に対する計画ベースラインに追加します。
-
オプティマイザは管理者により手動でロードされた計画のパフォーマンスは許容範囲にあると見なすため、手動でロードされた計画は常に承認済とマークされます。DBMS_SPM.LOAD_PLANS_FROM_%
ファンクションでenabled
パラメータをNO
に設定することで、計画を有効化せずにロードできます。
関連項目:
DBMS_SPM.LOAD_PLANS_FROM_%
ファンクションについてさらに学習するには、Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンスを参照してください
28.4 計画の選択
SQL 計画の選択とは、保存された計画履歴に基づいて計画変更を検出するオプティマイザの機能、およびパフォーマンスが低下する可能性を回避するために適切な計画を選択するSQL計画ベースラインの使用を指します。
データベースがSQL文のハード解析を実行すると、オプティマイザは最適なコスト計画を生成します。デフォルトでは、オプティマイザは次に、文に対するSQL計画ベースライン内で一致する計画を探します。計画ベースラインが存在しない場合は、データベースは最適なコスト計画を使用して文を実行します。
計画ベースラインが存在する場合は、オプティマイザの動作は、新たに生成された計画が計画ベースラインに含まれるかどうかによって決まります。
-
新しい計画がベースラインに含まれる場合、データベースは検出した計画を使用して文を実行します。
-
新しい計画がベースラインに含まれない場合、オプティマイザは新たに生成された計画を未承認とマークし、計画履歴に追加します。オプティマイザの動作は、計画ベースラインの内容によって決まります。
-
計画ベースラインに固定計画が含まれる場合、オプティマイザはコストが最も低い固定計画を使用します。
-
計画ベースラインに固定計画が含まれない場合、オプティマイザはコストが最も低いベースライン計画を使用します。
-
計画ベースライン内に再現可能な計画が含まれない場合(これはベースライン内のすべての計画が削除された索引を参照している場合に発生します)、オプティマイザは新たに生成されたコストベースの計画を使用します。
-
関連項目:
28.5 計画の展開
一般的に、SQL計画の展開は、オプティマイザが新しい計画を検証して既存のSQL計画ベースラインに追加するためのプロセスです。
28.5.1 計画の展開の目的
通常、文のSQL計画ベースラインは、1つの承認済の計画から開始します。
ただし、様々な条件の異なる計画とともに実行されると、SQL文の実行が良くなる場合があります。たとえば、値が異なる選択性になるバインド変数を使用したSQL文は、いくつかの最適な計画を持つ場合があります。マテリアライズド・ビューまたは索引の作成あるいは表の再パーティション化により、現在の計画が他の計画よりコストが高くなる場合があります。
新しい計画がSQL計画ベースラインに一度も追加されなかった場合、一部のSQL文のパフォーマンスが低下する可能性があります。したがって、新しい承認済の計画をSQL計画ベースラインに展開する必要がある場合があります。計画の展開は、SQL計画ベースラインに含める前に新しい計画のパフォーマンスを検証して、パフォーマンスの低下を防止します。
28.5.2 計画の展開の仕組み
計画の展開には、計画の検証と追加の両方が含まれます。
具体的には、計画の展開は次の個別のステップで構成されます。
-
検証
オプティマイザによって、承認されていない計画がSQL計画ベースラインに含まれる承認済の計画と少なくとも同じパフォーマンスであることが検証されます(計画の検証と呼ばれます)。
-
追加
承認されていない計画が承認済の計画と同様のパフォーマンスを示すことがデータベースによって証明されると、その計画がベースラインに追加されます。
計画の展開の標準的なケースでは、オプティマイザは前述のステップを順番に実行します。したがって、オプティマイザがSQL計画ベースラインと比較して計画のパフォーマンスを検証するまで、SQL計画管理で新しい計画は使用できません。ただし、 一方のステップを実行せずにもう一方のステップを実行するようにSQL計画管理を構成できます。次の図は、計画の展開で使用可能なパスを示しています。
28.5.3 計画の展開用のPL/SQLサブプログラム
DBMS_SPM
パッケージは、計画の展開で使用できるプロシージャとファンクションを提供します。
これらのサブプログラムはタスク・インフラストラクチャを使用します。たとえば、CREATE_EVOLVE_TASK
は展開タスクを作成し、EXECUTE_EVOLVE_TASK
はそれを実行します。すべてのタスク展開サブプログラムの名前には、文字列EVOLVE_TASK
が含まれます。
展開プロシージャは必要に応じて使用するか、自動的に実行されるようにサブプログラムを構成します。自動メンテナンス・タスクSYS_AUTO_SPM_EVOLVE_TASK
は、スケジュールされているメンテナンス・ウィンドウで毎日実行されます。このタスクにより次の処理が自動的に実行されます。
-
承認されていない計画を選択し、検証用にランク付けします。
-
パフォーマンスしきい値を満たしていれば、各計画を承認します。
関連項目:
-
DBMS_SPM
パッケージについて学習するには、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
28.6 SQL計画管理の記憶域アーキテクチャ
SQL計画管理インフラストラクチャでは、解析された文の署名と、承認済と未承認の両方の計画を記録します。
28.6.1 SQL管理ベース
SQL管理ベース(SMB)はデータ・ディクショナリ内の論理リポジトリです。
SMBの内容は次のとおりです。
-
SQL文のログ(SQL IDのみを含む)
-
SQL計画履歴(SQL計画ベースラインを含む)
-
SQLプロファイル
-
SQLパッチ
SMBには、SQLパフォーマンスの維持または向上のためにオプティマイザで使用できる情報が保存されます。
SMBはSYSAUX
表領域内にあり、自動セグメント領域管理を使用します。SMB全体がSYSAUX
表領域内に存在するため、この表領域が使用可能でない場合、データベースはSQL計画管理およびSQLチューニング機能を使用しません。
ノート:
SMBをプラガブル・データベースとともに使用すると、データの可視性と権限の要件が一致しない場合があります。コンテナ・データベース(CDB)内での管理機能の動作をまとめた表が記載されている『Oracle Database管理者ガイド』を参照してください。
関連項目:
SYSAUX
表領域について学習するには、Oracle Database管理者ガイドを参照してください
28.6.2 SQL文のログ
SQL計画の自動取得が有効になっている場合、SQL文のログには、オプティマイザがこれまでに評価してきた文の署名が含まれます。
SQLシグネチャは、大/小文字および空白が正規化されているSQL文のテキストを使用して計算されたハッシュ値です。オプティマイザは文を解析する際、シグネチャを作成します。
自動取得中、データベースはこの署名をSQL文のログ(SQLLOG$
)と照合してその署名が以前に確認されたことがあるかどうかを判断します。確認されたことがない場合、データベースはその署名をログに追加します。署名がすでにログにある場合は、データベースによりその文が繰返し可能なSQL文であることが確認されています。
ノート:
フィルタで文が除外される場合、その署名もログから除外されます。
例28-1 SQL文のロギング
この例は、データベースがどのように文のログ内で文を追跡し、繰返し可能な文に対して自動的にベースラインを作成するかを示しています。文のログの最初の問合せでは、追跡されたSQL文は1つもないことが示されます。AD_PRES
に対するhr.jobs
の問合せ後、ログには文が1つ追跡されていることが示されます。
SQL> ALTER SYSTEM SET OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES=true;
System altered.
SQL> SELECT * FROM SQLLOG$;
no rows selected
SQL> SELECT job_title FROM hr.jobs WHERE job_id = 'AD_PRES';
JOB_TITLE
-----------------------------------
President
SQL> SELECT * FROM SQLLOG$;
SIGNATURE BATCH#
---------- ----------
1.8096E+19 1
次に、セッションは別のjobs
問合せを実行します。ログには2つの文が追跡されていることが示されます。
SQL> SELECT job_title FROM hr.jobs WHERE job_id='PR_REP';
JOB_TITLE
-----------------------------------
Public Relations Representative
SQL> SELECT * FROM SQLLOG$;
SIGNATURE BATCH#
---------- ----------
1.7971E+19 1
1.8096E+19 1
DBA_SQL_PLAN_BASELINES
の問合せでは、どちらの文に対してもベースラインが存在しないことが示されます。これは、どちらの文も繰返し可能ではないためです。
SQL> SELECT SQL_HANDLE, SQL_TEXT
2 FROM DBA_SQL_PLAN_BASELINES
3 WHERE SQL_TEXT LIKE 'SELECT job_title%';
no rows selected
セッションがjob_id='PR_REP'
に対する問合せを再度実行します。これでこの文は繰返し可能になり、またSQL計画の自動取得が有効になっているため、データベースによりこの文に対する計画ベースラインが作成されます。job_id='AD_PRES'
に対する問合せは一度しか実行されていないため、これに対する計画ベースラインは存在しません。
SQL> SELECT job_title FROM hr.jobs WHERE job_id='PR_REP';
JOB_TITLE
-----------------------------------
Public Relations Representative
SQL> SELECT SQL_HANDLE, SQL_TEXT
2 FROM DBA_SQL_PLAN_BASELINES
3 WHERE SQL_TEXT LIKE 'SELECT job_title%';
SQL_HANDLE SQL_TEXT
-------------------- --------------------
SQL_f9676a330f972dd5 SELECT job_title FRO
M hr.jobs WHERE job_
id='PR_REP'
関連項目:
-
DBA_SQL_PLAN_BASELINES
について学習するには、『Oracle Databaseリファレンス』を参照してください。
28.6.3 SQL計画履歴
SQL計画履歴は、取得されたSQL実行計画のセットです。この履歴には、SQL計画ベースラインおよび未承認の計画が含まれます。
SQL計画管理では、データベースが既存のSQL計画ベースラインに対する新しいSQL実行計画を検出し、新しい計画を展開(検証)できるように履歴に記録します。展開は、データベースにより自動的に、またはDBAにより手動で開始されます。
Oracle Database 12cから、SQL計画履歴のすべてのSQL文に対する実行計画がSMBに保存されるようになりました。DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE
ファンクションは、SMBから計画をフェッチして表示します。Oracle Database 12cより前に作成された計画については、SMBに保存されていないため、ファンクションはSQL文をコンパイルして計画を生成する必要があります。
関連項目:
-
DBMS_XPLAN.DISPLAY_SQL_PLAN_BASELINE
ファンクションについて学習するには、Oracle Database PL/SQLパッケージおよびタイプ・リファレンスを参照してください
28.6.3.1 有効化された計画
有効化された計画は、オプティマイザの使用対象である計画です。
enabled
パラメータをYES
(デフォルト)に設定して計画をロードした場合、データベースは結果のSQL計画ベースラインを、承認されていない場合でも、自動的に有効とマークします。有効な計画を手動で無効な計画に変更できます。この場合、計画が承認済でもオプティマイザはその計画を使用できなくなります。
28.6.3.2 承認済の計画
承認済の計画はSQL文のSQL計画ベースラインに存在する計画であり、オプティマイザで使用できます。承認済の計画には、ヒント・セット、計画のハッシュ値、計画に関連するその他の情報が含まれます。
SQL文に対する計画履歴には、すべての計画(承認済と未承認の両方の計画)が含まれます。オプティマイザが計画ベースライン内に最初の承認済の計画を生成すると、それ以降のすべての承認されていない計画は計画履歴に追加され、検証を待ちますが、SQL計画ベースラインには追加されません。
28.6.3.3 固定計画
固定計画は、優先としてマークされた承認済の計画です。これにより、オプティマイザはベースライン内の固定計画のみを考慮するようになります。固定計画は、オプティマイザの計画選択プロセスに影響します。
ある文に対するSQL計画ベースラインに3つの計画が存在するとします。オプティマイザに、その内の2つの計画のみを優先させたいとします。次の図に示すように、この2つの計画を固定とマークすることにより、オプティマイザがこれらの計画からの最適な計画のみを使用し、残りの計画は無視するようにします。
1つ以上の有効な固定計画を含むベースラインに新しい計画を追加した場合、それらの計画を手動で固定と宣言しないかぎり、オプティマイザはそれらの計画を使用することはできません。