実行計画キャッシュ(Plan Cache)は、実行計画の生成回数を削減するために使用されます。
OceanBaseデータベースは、以前に生成された実行計画をキャッシュし、次回同じSQLを実行する際に直接使用できるようにします。これにより、繰り返し実行を回避し、実行プロセスを最適化します。この戦略は「Optimize Once」、すなわち「一度の最適化」と呼ばれています。
計画キャッシュは典型的なKey-Value構造であり、Keyはパラメータ化されたSQL文字列、ValueはそのSQLに対応する実行計画です。
各テナントは、各サーバー上に独立した計画キャッシュを持ち、そのサーバー上で処理されたSQL計画をキャッシュします。OceanBaseデータベースの計画キャッシュでは、SQLの実行計画はローカル計画、リモート計画、分散計画の3種類に分類されます。計画キャッシュ内では、同一のSQLが必要とするデータに応じて、同時に3種類の実行計画を持つ場合があります。
SQLの一つの実行計画について、OceanBaseデータベースはデフォルトで最初にSQLを実行した際に生成された計画のみを保持します。しかし、場合によっては、同一のSQLのパラメータ値が実行計画の選択に影響を与える可能性があるため、計画キャッシュは必要に応じて異なるパラメータ値に対して異なる実行計画を保持し、毎回の実行で最も適切な計画を使用できるようにします。
計画キャッシュのエビクト
計画キャッシュのエビクトとは、実行計画を計画キャッシュから削除し、計画キャッシュのメモリ使用量を削減することを指します。OceanBaseデータベースは、自動エビクトと手動エビクトの2種類の方法をサポートしています。
自動エビクト
自動エビクトとは、計画キャッシュが占用するメモリが計画をエビクトする必要があるメモリの上限(エビクト計画のハイウォーターマーク)に達した場合、計画キャッシュ内の計画を自動的にエビクトすることを指します。
実行計画エビクトのトリガー条件
一定間隔ごと(具体的な時間間隔は構成パラメータ
plan_cache_evict_intervalで設定)に、システムは異なるテナントの異なるサーバー上の計画キャッシュを自動的にチェックし、実行計画のエビクトが必要かどうかを判断します。ある計画キャッシュがそのテナントが設定したエビクト計画のハイウォーターマークを超えた場合、計画キャッシュのエビクトがトリガーされます。実行計画エビクトのポリシー
計画キャッシュのエビクトがトリガーされると、最後に使用されてから最も時間の経過した実行計画から優先的にエビクトします。一部の実行計画をエビクトした後、計画キャッシュの使用メモリがそのテナントが設定したエビクト計画のロウウォーターマークに達すると、エビクトを停止します。
計画キャッシュエビクト関連の構成
plan_cache_evict_intervalこの構成パラメータは、実行計画のエビクトが必要かどうかをチェックする間隔時間を設定します。ob_plan_cache_percentageこのシステム変数は、計画キャッシュが使用できるメモリがテナントメモリの割合を設定します。式は以下の通りです:計画キャッシュが使用できる最大メモリ(メモリ上限の絶対値)= テナントメモリ上限 * ob_plan_cache_percentage/100ob_plan_cache_evict_high_percentageこのシステム変数は、計画キャッシュのエビクトをトリガーするメモリサイズがメモリ上限の絶対値に占める割合を設定します。式は以下の通りです:計画キャッシュのエビクトをトリガーするメモリサイズ(エビクト計画のハイウォーターマーク)= メモリ上限の絶対値 * ob_plan_cache_evict_high_percentage/100ob_plan_cache_evict_low_percentageこのシステム変数は、計画キャッシュのエビクトを停止するメモリサイズがメモリ上限の絶対値に占める割合(エビクト計画のロウウォーターマーク)を設定します。式は以下の通りです:エビクトを停止するメモリ値(エビクト計画のロウウォーターマーク)= メモリ上限の絶対値 * ob_plan_cache_evict_low_percentage/100
例えば、テナントのメモリサイズが10GB、各パラメータ値を以下のように設定した場合:
ob_plan_cache_percentage=10ob_plan_cache_evict_high_percentage=90ob_plan_cache_evict_low_percentage=50
すると、次のように計算できます。
プランキャッシュのメモリ上限の絶対値 = 10GB × 10 / 100 = 1GB
プランのエビクティネーションのハイウォーターマーク = 1GB × 90 / 100 = 0.9GB
プランのエビクティネーションのローワーターマーク = 1GB × 50 / 100 = 0.5GB
この計算結果から、あるサーバー上でそのテナントのプランキャッシュ使用量が0.9GBを超えると、エビクティネーションがトリガーされ、最も長い間実行されていないプランが優先的に削除されます。使用メモリが0.5GBになるまでエビクティネーションは続行され、その後停止します。エビクティネーションの速度が新しいプランの生成速度に追いつかない場合、プランキャッシュの使用メモリがメモリ上限の絶対値である1GBに達すると、プランキャッシュに新しいプランは追加されなくなります。使用メモリが1GB未満になるまでエビクティネーションを実行し、その後にのみ新しいプランをプランキャッシュに追加します。
手動によるプランの削除
手動によるプランの削除とは、プランキャッシュ内のプランを強制的に削除することです。SQLステートメントは以下のとおりです:
ALTER SYSTEM FLUSH PLAN CACHE [[SQL_identifier] [database_list] tenant_list] [GLOBAL];
パラメータの説明は以下のとおりです。
SQL_identifier:SQLを指定するために使用します。形式はsql_id = 'xxx'です。このパラメータを指定しない場合、すべてのSQLのプランキャッシュをクリアします。説明
システムテナント
sysでSQL_identifierパラメータを使用する場合は、必ずtenant_listを指定してください。通常テナントで使用する場合は、tenant_listパラメータを指定できません。database_list:データベースを指定するために使用します。このパラメータを指定しない場合、すべてのプランキャッシュをクリアします。説明
システムテナント
sysでdatabase_listパラメータを使用する場合は、必ずtenant_listを指定してください。通常テナントで使用する場合は、tenant_listパラメータを指定できません。tenant_list:テナント範囲を指定するために使用します。tenant_listの形式はtenant = 'tenant_name, tenant_name....'です。tenant_listを指定しない場合、すべてのテナントのプランキャッシュをクリアします。指定した場合は、特定のテナントのプランキャッシュのみをクリアします。説明
tenant_listはシステムテナントsysのみが指定でき、他のテナントでは指定できません。つまり、他のテナントは自身のプランキャッシュのみをクリアできます。システムテナントがtenant_listを指定しない場合、すべてのテナントのプランキャッシュをクリアします。GLOBAL:GLOBALを指定しない場合、ローカルのプランキャッシュをクリアします。指定した場合、そのテナントが存在するすべてのサーバー上のプランキャッシュをクリアします。
プランキャッシュのリフレッシュ
プランキャッシュ内の実行計画は、さまざまな理由により無効になる可能性があります。その際、プランキャッシュ内の無効な計画をリフレッシュする必要があります。これは、該当する実行計画を削除し、再度最適化して生成した計画をプランキャッシュに追加することです。
以下のシナリオでは、実行計画が無効になり、リフレッシュが必要になります。
SQLでテーブルのスキーマ変更(インデックスの追加、列の削除や追加など)が行われた場合、そのSQLに対応するプランキャッシュ内の実行計画はリフレッシュされます。
SQLでテーブルの統計情報の再収集が必要な場合、そのSQLに対応するプランキャッシュ内の実行計画はリフレッシュされます。
プランキャッシュの使用制御
プランキャッシュの使用は、システム変数とヒントを使用して制御できます。
システム変数による制御
ob_enable_plan_cacheをTUREに設定すると、SQLリクエストがプランキャッシュを使用できることを意味します。FALSEに設定すると、SQLリクエストがプランキャッシュを使用できないことを意味します。デフォルトはTUREです。このシステム変数は、セッションレベルまたはグローバルレベルに設定できます。ヒントによる制御
- ヒント文
/*+ USE_PLAN_CACHE(NONE)*/を使用すると、プランキャッシュを使用しないことを意味します。 - ヒント文
/*+USE_PLAN_CACHE(DEFAULT)*/を使用すると、プランキャッシュを使用することを意味します。
- ヒント文
プランキャッシュのビュー
実行計画関連のビューには以下のものがあります:
(G)V$OB_PLAN_CACHE_STATは、現在のテナントが現在の(すべての)OBServerノード上のプランキャッシュ全体の状態を表示します。(G)V$OB_PLAN_CACHE_PLAN_STATは、現在のテナントが現在の(すべての)OBServerノード上のプランキャッシュにキャッシュされている各キャッシュオブジェクトの状態を表示します。(G)V$OB_PLAN_CACHE_PLAN_EXPLAINは、現在の(すべての)OBServerノード上のプランキャッシュにキャッシュされている物理実行計画を表示します。
ビューの詳細なパラメータ情報については、プランキャッシュ関連ビューを参照してください。