Partial Result Cache (PTRC) は、クエリ内の特定のオペレーターが生成する中間結果セットをキャッシュし、同じオペレーターの後続の実行時に再利用します。特に、オペレーターの相関パラメーターがドライビングテーブル内で多くの重複値を持つ場合に効果を発揮します。重複が多ければ多いほどキャッシュヒット率が高くなり、パフォーマンス向上も大きくなります。
仕組み
PTRC は以下の 2 点で「部分的(partial)」です。
クエリ全体の結果ではなく、特定のオペレーターの中間結果のみをキャッシュします。
対象となるオペレーターであっても、すべての中間結果をキャッシュするわけではなく、キャッシュ範囲はメモリ制限によって制約されます。
| 観点 | 従来のクエリキャッシュ | PTRC |
|---|---|---|
| 粒度 | クエリ全体の結果 | オペレーター単位の中間結果 |
| ライフサイクル | クエリ間で永続化 | 単一クエリ内のみ |
| ノード間の一貫性 | ノード間で不整合が発生する可能性あり | 不整合リスクなし |
| 適用範囲 | 狭い | 広い |
PTRC はキーと値のペア形式で結果を格納します。ここで、キーはオペレーターの相関パラメーター、値はキャッシュされた中間結果です。オペレーターが実行されるたびに、システムはキャッシュ内に該当するキーが存在するかを確認します。
キャッシュミス:オペレーターを実行し、その結果をキャッシュに追加します。
キャッシュヒット: キャッシュされた結果が直接返され、実行がスキップされます。
対象となるオペレーター
オペレーターが PTRC の対象となるには、以下の両方の条件を満たす必要があります。
相関パラメーターに依存しており、単一クエリ内で複数回実行されること。相関サブクエリやネステッドループ結合が代表的な例です。
実行間で相関パラメーターが変化しないこと。
RAND()やNOW()などの非決定性関数、またはユーザー定義関数 (UDF) を含むオペレーターは対象外です。
相関パラメーターとは、外部クエリから取得され、オペレーターが依存する値のことです。
例:TPC-H Q17
TPC-H Q17 は、PTRC の動作を実際のクエリで示したものです。
select
sum(l_extendedprice) / 7.0 as avg_yearly
from
lineitem,
part
where
p_partkey = l_partkey
and p_brand = 'Brand#34'
and p_container = 'MED BOX'
and l_quantity < (
select
0.2 * avg(l_quantity)
from
lineitem
where
l_partkey = p_partkey
);この相関サブクエリは、part と lineitem の結合結果の各行に対して 1 回ずつ実行されます。相関パラメーターは結合条件で使用されるドライビングテーブルのカラムである p_partkey です。結合結果には同じ p_partkey 値を持つ行が多数含まれるため、PTRC は各固有の p_partkey に対するサブクエリの結果をキャッシュし、同じ値を持つ後続の行で再利用します。キーは p_partkey、値は true or false です。

PTRC が有効になっていることを確認するには、クエリに対して EXPLAIN を実行します。実行計画のサブクエリの直前に Partial result cache という名前のオペレーターが表示されます。

前提条件
PTRC を有効化または調整する前に、ご利用のクラスターが以下の要件を満たしていることを確認してください。
MySQL 8.0 を実行している PolarDB for MySQL クラスター
リビジョンバージョン 8.0.2.2.9 以降
クラスターバージョンを確認するには、「エンジンバージョン」をご参照ください。
パラメーター
PTRC はデフォルトで有効になっており、6 つのパラメーターによって制御されます。これらのパラメーターは、PTRC の動作に関する以下の 3 つの側面を定義します:使用するかどうか、使用するタイミング、メモリがいっぱいになった場合の挙動。
| パラメーター | レベル | デフォルト | 有効な値 | 説明 |
|---|---|---|---|---|
partial_result_cache_enabled | グローバル/セッション | ON | ON, OFF | PTRC を有効または無効にします。 |
partial_result_cache_cost_threshold | グローバル/セッション | 10000 | 0–18446744073709551615 | クエリコストのしきい値です。全体のクエリコストがこの値を超える場合にのみ、PTRC が検討されます。 |
partial_result_cache_check_frequency | グローバル/セッション | 200 | 0–18446744073709551615 | 動的フィードバックメカニズムによるヒット率の再計算間隔(キャッシュミス回数)です。 |
partial_result_cache_low_hit_rate | グローバル/セッション | 20 | 0–100 | 下限ヒット率しきい値(パーセント)。推定ヒット率がこの値を下回る場合は PTRC は使用されず、実際のヒット率がこの値を下回った場合はクエリ実行中に PTRC が無効になります。partial_result_cache_high_hit_rate より小さい値である必要があります。 |
partial_result_cache_high_hit_rate | グローバル/セッション | 70 | 0–100 | 上限ヒット率しきい値(パーセント)。メモリ制限に達した場合、ヒット率がこの値を超えていれば、キャッシュされた結果がディスクにダンプされます。partial_result_cache_low_hit_rate より大きい値である必要があります。 |
partial_result_cache_max_mem_size | グローバル/セッション | 67108864 | 0–18446744073709551615 | 単一クエリで PTRC が使用できる最大メモリサイズ(バイト単位)。デフォルトは 64 MiB です。 |
オプティマイザーによる PTRC 使用判断
PTRC はリソースを消費します。具体的には、オペレーターの実行ごとにキャッシュ検索を行い、キャッシュされた結果をメモリに保持します。クエリ オプテマイザーは、partial_result_cache_cost_threshold および partial_result_cache_low_hit_rate を用いて、そのコストに見合う効果があるかどうかを判断します。
ステップ 1:コストチェック
全体のクエリコストが partial_result_cache_cost_threshold を下回る場合、オプティマイザーは PTRC を完全にスキップします。短時間で完了するクエリでは、キャッシュ検索のオーバーヘッドがパフォーマンス向上を上回る可能性があるためです。
ステップ 2:ヒット率の推定
クエリコストがしきい値を超えると、オプティマイザーは対象となるすべての演算子を特定し、それぞれのヒット率を推定します:
hit_rate = (fanout - ndv) / fanoutfanout:オペレーターの総実行回数。ndv:相関パラメーター(キャッシュキー)の異なる値の数。
推定ヒット率が partial_result_cache_low_hit_rate を下回る場合、そのオペレーターに対して PTRC は使用されません。
推定が不可能な場合
オプティマイザーは、ndv の推定にインデックスまたはヒストグラムを使用します。相関パラメーターのカラムにいずれも存在しない場合、ndv を正確に推定できません。その場合、オプティマイザーはヒット率の推定なしに PTRC を有効化し、実行時の動的フィードバックメカニズムに判断を委ねます。
動的フィードバックメカニズム
実行時、PTRC は自身のヒット率とメモリ使用量をモニターし、それに応じて動作を調整します。
ヒット率は、partial_result_cache_check_frequency 回のキャッシュミスごと(デフォルト:200 回ごと)に再計算されます。また、メモリ使用量が partial_result_cache_max_mem_size に達した場合にも再計算されます。
現在のヒット率に基づき、以下のいずれかの操作が実行されます。
| 条件 | 操作 |
|---|---|
ヒット率 < partial_result_cache_low_hit_rate | クエリの残りの部分で PTRC を無効にします。 |
ヒット率 > partial_result_cache_high_hit_rate | メモリ内のキャッシュをディスクにダンプします。新しいキャッシュエントリーもディスクに書き込まれます。ヒット率が高いため、パフォーマンスへの影響は最小限に抑えられます。 |
| ヒット率が 2 つのしきい値の間にある場合 | LRU(Least Recently Used:最も最近使われていないもの)方式によるエビクションを適用します。つまり、使用頻度が最も低いエントリーを削除して新しいデータをキャッシュします。再度メモリがいっぱいになった場合は、フィードバックメカニズムが再度トリガーされます。 |
メモリ制限に達した場合、そのクエリ内で PTRC が有効になっているすべてのオペレーターに対してフィードバックメカニズムがトリガーされます。
パフォーマンスに関する考慮事項
PTRC によるパフォーマンス向上の程度は、以下の 2 つの要因によって決まります。
オペレーターのコスト:キャッシュ対象のオペレーターのコストが高ければ高いほど、パフォーマンス向上の効果が大きくなります。コストが低いオペレーターでは、改善効果はわずかです。
キャッシュヒット率:ヒット率が高ければ高いほど、パフォーマンス向上の効果が大きくなります。
TPC-H Q17 では、キャッシュヒット率は 96% です。以下の図は、PTRC を有効にした場合のクエリとその実行計画、およびパフォーマンス向上の様子を示しています。



PTRC は、相関パラメーターに依存する複雑なオペレーターを含むクエリ向けに設計されています。PTRC が適しているオペレーターには、相関サブクエリやネステッドループ結合(内部結合、外部結合、セミ結合、アンチ結合)が含まれます。