この章では、SQL計画の管理を使用してSQL実行計画を管理する方法について説明します。SQL計画の管理を使用すると、SQL計画の情報を取得、選択および改良するためのコンポーネントが用意されているため、SQL文の実行計画に対する突然の変更によるパフォーマンスの低下を回避できます。
SQL文の実行計画は、次のような様々な変更の影響を受けます。
新しいバージョンのオプティマイザ
オプティマイザ統計およびオプティマイザ・パラメータに対する変更
スキーマ定義およびメタデータ定義に対する変更
システム設定に対する変更
SQLプロファイルの作成
イベントには、実行計画に取り消すことができない変更(索引の削除など)を行うものがあります。これらの変更はSQLパフォーマンスが低下する原因となり、手動で修正することは難しく多くの時間を要する可能性があります。
Oracle DatabaseのSQLチューニング機能は、オプティマイザで適切にチューニングされた計画を作成できるようにSQLプロファイルを生成しますが、これは事後対応メカニズムであるため、大幅な変更が発生した場合には安定したパフォーマンスを保証できません。SQLチューニングは、パフォーマンスの問題が発生して特定された後にしか解決できません。たとえば、SQL文が計画の変更により高負荷文となっても、計画の変更後でなければSQLチューニングでは解決できません。
SQL計画の管理は予防メカニズムで、SQL文の実行計画を長期的に記録および評価し、効率的であると確認された一連の既存の計画から成るSQL計画ベースラインを構築します。SQL計画ベースラインは、システムでの変更の発生に関係なく、対応するSQL文のパフォーマンスを維持するために使用されます。
SQL計画の管理によってSQLパフォーマンスを向上または維持できる一般的な使用例は、次のとおりです。
新しいバージョンのオプティマイザをインストールするデータベースのアップグレードでは、通常、ほんのわずかなSQL文に対して計画の変更が発生しますが、ほとんどの計画の変更においてパフォーマンスに変化や向上は見られません。しかし、特定の計画の変更は、パフォーマンスの低下の原因となることがあります。SQL計画ベースラインを使用すると、データベースのアップグレードがもたらすパフォーマンスの低下の可能性は最小限に抑えられます。
継続的なシステムおよびデータの変更は、一部のSQL文の計画に影響を及ぼし、パフォーマンスの低下を招く可能性があります。SQL計画ベースラインを使用すると、パフォーマンスの低下を最小限に抑えてSQLパフォーマンスを安定させることが簡単にできます。
新しいアプリケーション・モジュールのデプロイメントは、新しいSQL文をシステムに導入することを意味します。アプリケーション・ソフトウェアでは、標準的なテスト構成で開発された適切なSQL実行計画を新しいSQL文に使用します。実際のシステム構成がテスト構成とは大幅に異なる場合は、SQL計画ベースラインを長期的に改良してパフォーマンスを向上させることができます。
この章には次の項があります。
SQL計画ベースラインの管理には、次の3つのフェーズがあります。
SQL計画ベースラインの取得フェーズ中、Oracle DatabaseではSQL文の実行に関する情報を記録し、計画の変更を検出して新しい計画の使用が安全かどうかを判断します。そのために、データベースでは個々のSQL文について計画の履歴を保持します。非定型SQL文は繰り返し使用されず、パフォーマンスが低下することはないため、繰返し可能なSQL文についてのみ計画の履歴は保持されます。
繰返し可能なSQL文を認識するために文のログが保持されます。このログには、オプティマイザが長期的に評価してきた様々なSQL文の識別子が含まれます。SQL文は、ログに記録された後に再度解析または実行されると、繰返し可能と認識されます。
SQL文ごとに、オプティマイザによって生成された計画がすべて含まれる計画の履歴が保持されます。しかし、計画の履歴の計画をオプティマイザで使用できるようにするには、その計画がパフォーマンスの低下の原因ではないことを確認する必要があります。計画の履歴の容認された計画全部を1つにまとめたものがSQL計画ベースラインです。
SQL計画ベースラインの取得フェーズは、繰返し可能なSQL文の計画の履歴およびSQL計画ベースラインを自動的に取得するように構成できます。あるいは、一連の計画を手動でSQL計画ベースラインとしてロードすることも可能です。
この項では、次の項目について説明します。
計画の自動取得を使用可能にすると、オプティマイザによって提供される情報を使用して、SQL文の計画の履歴が自動的に作成および保持されます。計画の履歴には、実行計画を再作成するためにオプティマイザで使用される関連情報(SQLテキスト、アウトライン、バインド変数、コンパイル環境など)が含まれます。
SQL文に対して生成される最初の計画は、オプティマイザでの使用を容認されたとしてマークされ、計画の履歴とSQL計画ベースラインの両方に挿入されます。後続の計画はすべて計画の履歴に挿入されます。パフォーマンスの低下の原因ではないことを確認された計画は、SQL計画ベースラインの改良フェーズ中にSQL計画ベースラインに追加されます。
計画の自動取得を使用可能にするには、OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES
初期化パラメータをTRUE
に設定します。デフォルトでは、このパラメータはFALSE
に設定されます。
SQL計画ベースラインを作成するもう1つの方法は、一連のSQL文に対する既存の計画をSQL計画ベースラインとして手動でロードする方法です。手動でロードされた計画は、パフォーマンスについて検証されていませんが、既存または新規のSQL計画ベースラインに容認された計画として追加されます。計画の手動ロードは、計画の自動取得と組み合せて使用することも、代替方法として使用することもできます。次の方法で、計画の手動ロードを実行できます。
SQLチューニング・セットから計画をロードするには、次のようにDBMS_SPM
パッケージのLOAD_PLANS_FROM_SQLSET
ファンクションを使用します。
DECLARE my_plans pls_integer; BEGIN my_plans := DBMS_SPM.LOAD_PLANS_FROM_SQLSET( sqlset_name => 'tset1'); END; /
この例では、tset1
というSQLチューニング・セットに保存された計画がデータベースによってロードされます。LOAD_PLANS_FROM_SQLSET
ファンクションで使用されるその他のパラメータの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
自動ワークロード・リポジトリ(AWR)から計画をロードするには、この項で説明するようにLOAD_PLANS_FROM_SQLSET
ファンクションを使用する前に、AWRスナップショットに保存された計画をSQLチューニング・セットにロードします。
カーソル・キャッシュから計画をロードするには、次のようにDBMS_SPM
パッケージのLOAD_PLANS_FROM_CURSOR_CACHE
ファンクションを使用します。
DECLARE my_plans pls_integer; BEGIN my_plans := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE( sql_id => '99twu5t2dn5xd'); END; /
この例では、sql_id
で識別されるSQL文についてカーソル・キャッシュで検索された計画がOracle Databaseによってロードされます。カーソル・キャッシュの計画は、次の要素により識別可能です。
SQL識別子(SQL_ID
)
SQLテキスト(SQL_TEXT
)
次のいずれかの属性
PARSING_SCHEMA_NAME
MODULE
ACTION
関連項目: LOAD_PLANS_FROM_CURSOR_CACHE ファンクションの使用方法の詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
SQL計画ベースラインの選択フェーズ中、Oracle Databaseでは格納された計画の履歴に基づいて計画の変更を検出し、一連のSQL文に対してパフォーマンスの低下の可能性を回避する計画を選択します。
SQL文がコンパイルされるたびに、オプティマイザは、まず、コストベースの検索方法を使用してコストが最適な計画を構築し、次にSQL計画ベースラインで合致する計画を検出しようとします。合致するものが検出された場合、オプティマイザはその計画を使用します。合致するものがない場合は、SQL計画ベースラインの容認された計画ごとにコストを評価し、コストが最も低い計画を選択します。オプティマイザによって検出されたコストが最適な計画は、SQL文の計画の履歴のどの計画とも合致しなければ新しい計画となり、容認されていない計画として計画の履歴に追加されます。新しい計画は、パフォーマンスの低下の原因ではないことを確認されるまで使用されません。しかし、システムの変更(削除された索引など)によって容認された計画がすべて再生不可能になった場合は、オプティマイザはコストが最適な計画を選択します。このように、SQL計画ベースラインが存在するために、オプティマイザはSQL文に対して慎重な計画の選択方法を使用することになります。
SQL計画ベースラインを使用可能にするには、OPTIMIZER_USE_SQL_PLAN_BASELINES
初期化パラメータをTRUE
に設定します(デフォルト)。
SQL計画ベースラインの改良フェーズ中、データベースでは新しい計画のパフォーマンスを評価し、より優れたパフォーマンスの計画をSQL計画ベースラインに組み込みます。
オプティマイザがSQL文に対して新しい計画を検出すると、その計画は、容認されていない計画として計画の履歴に追加されます。次に、SQL計画ベースラインのパフォーマンスと比較してその計画のパフォーマンスが検証されます。容認されていない計画がパフォーマンスの低下の原因ではないことが確認されると、容認された計画に変わってSQL計画ベースラインに組み込まれます。容認されていない計画の成功した検証では、容認されていない計画のパフォーマンスとSQL計画ベースラインから選択された計画のパフォーマンスを比較し、容認されていない計画のパフォーマンスの方が良好であることが確認されます。
この項では、SQL計画ベースラインの改良方法について説明します。この項には、次の項目があります。
既存のSQL計画ベースラインは、カーソル・キャッシュまたはSQLチューニング・セットから計画を手動でロードすることにより改良できます。計画を手動でSQL計画ベースラインにロードすると、ロードされた計画が容認された計画として追加されます。
PL/SQLファンクションDBMS_SPM.EVOLVE_SQL_PLAN_BASELINE
は、オプティマイザにより既存の計画ベースラインの計画の履歴に追加された新規計画を改良しようと試みます。ファンクションにより、新規計画のパフォーマンスの方が対応するSQL計画ベースラインから選択された計画より優れていると判断されると、その新規計画は容認された計画として追加されます。
次に、DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE
ファンクションの例を示します。
SET SERVEROUTPUT ON SET LONG 10000 DECLARE report clob; BEGIN report := DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE( sql_handle => 'SYS_SQL_593bc74fca8e6738'); DBMS_OUTPUT.PUT_LINE(report); END; /
出力:
REPORT -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- Evolve SQL Plan Baseline Report -------------------------------------------------------------------------------- Inputs: ------- SQL_HANDLE = SYS_SQL_593bc74fca8e6738 PLAN_NAME = TIME_LIMIT = DBMS_SPM.AUTO_LIMIT VERIFY = YES COMMIT = YES Plan: SYS_SQL_PLAN_ca8e6738a57b5fc2 ----------------------------------- Plan was verified: Time used .07 seconds. Passed performance criterion: Compound improvement ratio >= 7.32. Plan was changed to an accepted plan. Baseline Plan Test Plan Improv. Ratio ------------- --------- ------------- Execution Status: COMPLETE COMPLETE Rows Processed: 40 40 Elapsed Time(ms): 23 8 2.88 CPU Time(ms): 23 8 2.88 Buffer Gets: 450 61 7.38 Disk Reads: 0 0 Direct Writes: 0 0 Fetches: 0 0 Executions: 1 1 ------------------------------------------------------------------------------- Report Summary ------------------------------------------------------------------------------- Number of SQL plan baselines verified: 1. Number of SQL plan baselines evolved: 1.
この例では、対応するSQLハンドルで識別されるSQL文の計画が、Oracle Databaseによって正常に改良されました。または、DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE
を使用して次のものを指定できます。
改良する特定の計画の名前
改良する計画のリスト
値なし
この場合、SQL管理ベースで現在容認されていないすべての計画が改良されます。
関連項目: DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE ファンクションの使用方法の詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。 |
SQLチューニング・アドバイザでSQL文をチューニングする場合、アドバイザによりチューニングされた計画が検出され、そのパフォーマンスが対応するSQL計画ベースラインから選択された計画より優れていると判断されると、SQLプロファイルを受け入れるよう推奨されます。SQLプロファイルが受け入れられると、チューニング済の計画は対応するSQL計画ベースラインに追加されます。ただし、SQLチューニング・アドバイザでは、計画の履歴内で容認されていない既存の計画は検証されません。
Oracle Database 11gでは、メンテナンス期間中に自動構成されたタスクによってSQLチューニング・アドバイザが実行されます。この自動SQLチューニング・タスクの対象は高負荷SQL文です。高負荷SQL文は、自動ワークロード・リポジトリ(AWR)スナップショットで収集される実行パフォーマンス・データによって識別されます。SQLチューニング・アドバイザによって生成されるSQLプロファイルの推奨事項は、自動SQLチューニング・タスクによって実装されます。したがって、チューニング済の計画は、識別された高負荷SQL文のSQL計画ベースラインに自動的に追加されます。
SQL計画ベースラインにFIXED
属性がYES
に設定された使用可能な計画が1つでも含まれる場合、そのSQL計画ベースラインは固定されます。固定SQL計画ベースラインは、任意のSQL文に対応する使用可能な計画のセット(通常は1つの計画)を固定する場合や、固定計画としてアウトライン計画をロードすることにより既存のストアド・アウトラインを移行する場合に使用できます。
固定SQL計画ベースラインに固定されていない計画も含まれる場合、オプティマイザでは、固定されていない計画より固定計画の方が優先されます。つまり、オプティマイザでは、固定されていない計画のコストの方が低い場合でも、最小のコストの固定計画が選択されます。再生可能な固定計画が存在しない場合は、固定されていない計画のうち最良のものが選択されます。
オプティマイザは、固定SQL計画ベースラインに新規計画を追加しません。新規計画は自動的に追加されないため、DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE
を実行しても固定SQL計画ベースラインは改良されません。ただし、新規計画をカーソル・キャッシュまたはSQLチューニング・セットから手動でロードすれば、固定SQL計画ベースラインを改良できます。
SQLチューニング・アドバイザを使用して固定SQL計画ベースラインを持つSQL文をチューニングする場合、SQLプロファイルの推奨は特別な意味を持ちます。SQLプロファイルが受け入れられると、チューニング済の計画は、固定されていない計画として固定SQL計画ベースラインに追加されます。ただし、前述のとおり、再生可能な固定計画が存在するかぎり、オプティマイザではチューニング済の計画は使用されません。したがって、SQLチューニングのメリットは実現されない可能性があります。チューニング済の計画を使用可能にするには、FIXED
属性をYES
に設定し、チューニング済の計画を手動で固定計画に変更します。
特定の文についてSQL計画ベースラインに保存された計画を表示するには、次のようにDBMS_XPLAN
パッケージのDISPLAY_SQL_PLAN_BASELINE
ファンクションを使用します。
select * from table( dbms_xplan.display_sql_plan_baseline( sql_handle=>'SYS_SQL_209d10fabbedc741', format=>'basic'));
DISPLAY_SQL_PLAN_BASELINE
ファンクションは、ハンドル(sql_handle
)で指定したSQL文について1つ以上の実行計画を表示します。あるいは、計画名(plan_name
)を指定して1つの計画を表示することもできます。DISPLAY_SQL_PLAN_BASELINE
ファンクションで使用されるその他のパラメータの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
このファンクションは、SQL管理ベースに保存された計画の情報を使用して計画の詳細を表示します。この例では、DISPLAY_SQL_PLAN_BASELINE
ファンクションは、ハンドルSYS_SQL_209d10fabbedc741
で指定されたSQL文の実行計画を表示します。
SQL handle: SYS_SQL_209d10fabbedc741 SQL text: select cust_last_name, amount_sold from customers c, sales s where c.cust_id=s.cust_id and cust_year_of_birth=:yob ---------------------------------------------------------------------------------- ---------------------------------------------------------------------------------- Plan name: SYS_SQL_PLAN_bbedc741a57b5fc2 Enabled: YES Fixed: NO Accepted: NO Origin: AUTO-CAPTURE ---------------------------------------------------------------------------------- Plan hash value: 2776326082 ---------------------------------------------------------------------------------- | Id | Operation | Name | ---------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | HASH JOIN | | | 2 | TABLE ACCESS BY INDEX ROWID | CUSTOMERS | | 3 | BITMAP CONVERSION TO ROWIDS | | | 4 | BITMAP INDEX SINGLE VALUE | CUSTOMERS_YOB_BIX | | 5 | PARTITION RANGE ALL | | | 6 | TABLE ACCESS FULL | SALES | ---------------------------------------------------------------------------------- ---------------------------------------------------------------------------------- Plan name: SYS_SQL_PLAN_bbedc741f554c408 Enabled: YES Fixed: NO Accepted: YES Origin: MANUAL-LOAD ---------------------------------------------------------------------------------- Plan hash value: 4115973128 ---------------------------------------------------------------------------------- | Id | Operation | Name | ---------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | 1 | NESTED LOOPS | | | 2 | NESTED LOOPS | | | 3 | TABLE ACCESS BY INDEX ROWID | CUSTOMERS | | 4 | BITMAP CONVERSION TO ROWIDS | | | 5 | BITMAP INDEX SINGLE VALUE | CUSTOMERS_YOB_BIX | | 6 | PARTITION RANGE | | | 7 | BITMAP CONVERSION TO ROWIDS | | | 8 | BITMAP INDEX SINGLE VALUE | SALES_CUST_BIX | | 9 | TABLE ACCESS BY LOCAL INDEX ROWID | SALES | ----------------------------------------------------------------------------------
また、DBA_SQL_PLAN_BASELINES
ビューに対してSELECT
文を直接使用してSQL計画ベースラインの情報を表示することもできます。
select sql_handle, plan_name, enabled, accepted, fixed from dba_sql_plan_baselines; SQL_HANDLE PLAN_NAME ENA ACC FIX ------------------------------------------------------------------------ SYS_SQL_209d10fabbedc741 SYS_SQL_PLAN_bbedc741a57b5fc2 YES NO NO SYS_SQL_209d10fabbedc741 SYS_SQL_PLAN_bbedc741f554c408 YES YES NO
SQL管理ベース(SMB)は、SYSAUX
表領域にあるデータ・ディクショナリの一部です。文のログ、計画の履歴およびSQL計画ベースラインの他、SQLプロファイルが保存されます。週次で未使用の計画およびログを消去できるようにするには、SMBで自動領域管理を使用可能に構成します。
また、一連のSQL文について計画をSMBに手動で追加することもできます。この機能は、11gより前のリリースからOracle Databaseをアップグレードする場合に特に便利です。新しいバージョンのオプティマイザを使用したために計画が低下することを最小限に抑えることができるためです。
SMBは全体がSYSAUX
表領域内に格納されるため、この表領域が使用できない場合、SQL計画の管理およびSQLチューニング機能は使用されません。
この項では、次の項目について説明します。
SQL管理ベースで使用されるディスク領域は、SYSAUX
表領域のサイズに基づいた制限と定期的に照合されます。デフォルトでは、SMBの制限はSYSAUX
表領域のサイズの10%程度です。この制限の許容範囲は1〜50%です。週次のバックグラウンド・プロセスによってSMBが占有する合計領域が測定され、定義された制限を超えると、アラートが生成されてアラート・ログに書き込まれます。アラートは、SMB領域の制限またはSYSAUX
表領域のサイズを増やすか、SQL管理オブジェクト(SQL計画ベースラインやSQLプロファイル)を消去してSMBで使用されるディスク領域を減らさないかぎり、毎週生成されます。
制限の比率を変更するには、次のようにDBMS_SPM
パッケージのCONFIGURE
プロシージャを使用します。
BEGIN DBMS_SPM.CONFIGURE( 'space_budget_percent',30); END; /
この例では、領域の制限は30%に変更されます。CONFIGURE
プロシージャで使用されるその他のパラメータの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
週次にスケジュールされた消去タスクにより、SQL計画の管理で使用されるディスク領域は管理されます。このタスクは、メンテナンス期間に自動化タスクとして実行されます。54週以上使用されていない計画はすべて消去されます。消去対象は、その計画のSMBに保存されたLAST_EXECUTED
タイムスタンプで識別されます。53週という期間により、年次のSQL処理アクティビティの間、計画の情報は使用可能であることが保証されます。未使用計画の保存期間の範囲は5〜523週間(約10年)です。
保存期間を構成するには、次のようにDBMS_SPM
PL/SQLパッケージのCONFIGURE
プロシージャを使用します。
BEGIN DBMS_SPM.CONFIGURE( 'plan_retention_weeks',105); END; /
この例では、保存期間は105週間に変更されます。CONFIGURE
プロシージャで使用されるその他のパラメータの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。
SQL管理ベースの現在の構成設定は、DBA_SQL_MANAGEMENT_CONFIG
ビューを使用して表示できます。次の問合せにより、この情報が表示されます。
select parameter_name, parameter_value from dba_sql_management_config; PARAMETER_NAME PARAMETER_VALUE ------------------------------ --------------- SPACE_BUDGET_PERCENT 30 PLAN_RETENTION_WEEKS 105
Oracle Databaseでは、インポートおよびエクスポート・ユーティリティやOracle Data Pumpを使用したSQL計画ベースラインのエクスポートおよびインポートをサポートしています。DBMS_SPM
パッケージを使用して、SQL計画ベースラインの圧縮および解凍に使用されるステージング表を定義します。
システム間で一連のSQL計画ベースラインをインポートするには、次のようにします。
元のシステムで、次のようにCREATE_STGTAB_BASELINE
プロシージャを使用してステージング表を作成します。
BEGIN DBMS_SPM.CREATE_STGTAB_BASELINE( table_name => 'stage1'); END; /
この例では、stage1
というステージング表が作成されます。
SQL管理ベースからエクスポートするSQL計画ベースラインを、次のようにPACK_STGTAB_BASELINE
ファンクションを使用してステージング表に圧縮します。
DECLARE my_plans number; BEGIN my_plans := DBMS_SPM.PACK_STGTAB_BASELINE( table_name => 'stage1', enabled => 'yes', creator => 'dba1'); END; /
この例では、ユーザーdba1
が作成した有効な計画ベースラインをすべてステージング表stage1
に圧縮します。SQL計画ベースラインは、計画名(plan_name
)、SQLハンドル(sql_handle
)、その他の計画の条件を使用して選択できます。table_name
パラメータは必須です。
エクスポート・コマンドまたはOracle Data Pumpを使用して、ステージング表stage1
をフラット・ファイルにエクスポートします。
このフラット・ファイルをターゲット・システムに送信します。
インポート・コマンドまたはOracle Data Pumpを使用して、ステージング表stage1
をフラット・ファイルからインポートします。
ターゲット・システムで、次のようにUNPACK_STGTAB_BASELINE
ファンクションを使用してSQL計画ベースラインをステージング表からSQL管理ベースに解凍します。
DECLARE my_plans number; BEGIN my_plans := DBMS_SPM.UNPACK_STGTAB_BASELINE( table_name => 'stage1', fixed => 'yes'); END; /
この例では、ステージング表stage1
に格納された固定計画ベースラインがすべて解凍されます。
DBMS_SPM
パッケージの使用方法の詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。