実行計画キャッシュ(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
計算結果は次のとおりです:
プランキャッシュメモリ上限の絶対値 = 10G * 10 / 100 = 1 GB
エビクトプランのハイウォーターマーク = 1G * 90 / 100 = 0.9 GB
エビクトプランのロウウォーターマーク = 1G * 50 / 100 = 0.5 GB
計算結果からわかるように、そのテナントがあるサーバー上でプランキャッシュの使用量が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に対応するプランキャッシュ内の実行計画はリフレッシュされます。
プランキャッシュの使用制御
プランキャッシュは、システム変数とHintを使用して使用を制御できます。
システム変数による制御
ob_enable_plan_cacheをTUREに設定すると、SQLリクエストがプランキャッシュを使用できることを意味します。FALSEに設定すると、SQLリクエストがプランキャッシュを使用できないことを意味します。デフォルトはTUREです。このシステム変数は、セッションレベルまたはグローバルレベルに設定できます。Hintによる制御
- Hintステートメント
/*+ USE_PLAN_CACHE(NONE)*/を使用すると、プランキャッシュを使用しないことを意味します。 - Hintステートメント
/*+USE_PLAN_CACHE(DEFAULT)*/を使用すると、プランキャッシュを使用することを意味します。
- Hintステートメント
プランキャッシュに関するビュー
実行計画に関連するビューは以下のとおりです:
(G)V$OB_PLAN_CACHE_STATは、現在のテナントが現在の(すべての)OBServerノード上のプランキャッシュ全体の状態を表示します。(G)V$OB_PLAN_CACHE_PLAN_STATは、現在のテナントが現在の(すべての)OBServerノード上のプランキャッシュにキャッシュされている各キャッシュオブジェクトの状態を表示します。(G)V$OB_PLAN_CACHE_PLAN_EXPLAINは、現在の(すべての)OBServerノード上のプランキャッシュにキャッシュされている物理実行計画を表示します。
ビューの詳細なパラメータ情報については、プランキャッシュ関連ビューを参照してください。