PolarDB は推移述語生成をサポートしています。この機能により、SQL クエリ内の述語条件を詳細に分析し、新しい述語を抽出して導出できます。このプロセスには、等価関係と非等価関係の両方が含まれます。その結果、PolarDB はより正確な述語条件を生成できるため、クエリ オプティマイザーはインデックス選択や結合順序などの重要な決定をより効果的に行うことができます。新しい述語を導出することで、オプティマイザーはより広範囲の実行計画を検討できるようになり、クエリの パフォーマンスが最適化されます。
前提条件
この機能は、リビジョン バージョン 8.0.2.2.23 以後のデータベースエンジン MySQL 8.0.2 を使用するクラスターでサポートされています。データベースエンジンのバージョンのクエリ方法については、「エンジンのバージョンのクエリ」をご参照ください。
シナリオ
PolarDB では、推移述語生成によって述語プッシュダウンが強化されます。これには、以下の実装が含まれますが、これらに限定されません。
<b>HAVING</b>句から<b>WHERE</b>句への条件プッシュダウン: これにより、集約前に適用できるHAVING条件がWHERE条件に変換され、集約対象のデータ量が削減されます。詳細については、「条件プッシュダウン(HAVING 句から WHERE 句へ)」をご参照ください。<b>WHERE</b>句から派生テーブルへの条件プッシュダウン: 外部クエリのWHERE条件が派生テーブルにプッシュダウンされ、早期のデータ フィルタリングが実行されます。詳細については、「条件プッシュダウン(WHERE 句から派生テーブルへ)」をご参照ください。<b>WHERE</b>句から<b>IN</b>サブクエリへの条件プッシュダウン: 外部クエリのWHERE条件がINサブクエリにプッシュダウンされ、サブクエリの実行効率が向上します。詳細については、「条件プッシュダウン(WHERE 句から IN サブクエリへ)」をご参照ください。結合条件からマテリアライズド派生テーブルへのプッシュダウン: 結合条件がマテリアライズド派生テーブルに直接適用され、不要なデータ スキャンが最小限に抑えられます。詳細については、「条件プッシュダウン(結合条件からマテリアライズド派生テーブルへ)」をご参照ください。
推移述語生成の主な目的は、順列や組み合わせによって変数間の関係を導出することではなく、できるだけ多くの単一テーブル条件を生成することです。このアプローチにより、システムは後続の最適化ステージで使用する新しい有効なフィルター条件を識別して作成できるようになり、データセットが絞り込まれ、クエリのパフォーマンスと効率が向上します。このプロセスは、PolarDB の述語プッシュダウン機能を強化するだけでなく、クエリ オプティマイザーが複雑なクエリをよりインテリジェントに処理できるようにし、最終的にシステム パフォーマンスを向上させます。
推移述語生成は、以下のシナリオに適用できます。
非等価関係と等価関係の両方に対する単純な推移述語生成。例:
-- オリジナル SQL SELECT * FROM t1, v1 WHERE v1.a > t1.a AND t1.a > 1 -- 派生 SQL SELECT * FROM t1, v1 WHERE v1.a > t1.a AND t1.a > 1 AND v1.a > 1 -- オリジナル SQL SELECT * FROM t1, v1 WHERE v1.b < t1.c AND t1.c < t2.c AND t2.c = 1; -- 派生 SQL SELECT * FROM t1, v1 WHERE v1.b < t1.c AND t1.c < t2.c AND t2.c = 1 AND v1.b < 1 AND t1.c < 1;交換法則に準拠する式も推移述語生成の対象となります。例:
-- オリジナル SQL SELECT * FROM t1, v2 WHERE v2.c1 < t1.c2 + t1.c1 AND t1.c1 + t1.c2 < 2; -- 派生 SQL SELECT * FROM t1, v2 WHERE v2.c1 < t1.c2 + t1.c1 AND t1.c1 + t1.c2 < 2 AND v2.c1 < 2;等価関係に基づく複雑な推移述語生成。例:
-- オリジナル SQL SELECT * FROM t3, v3 WHERE v3.c2 = t3.c2 AND t3.c2 LIKE "%00%"; -- 派生 SQL SELECT * FROM t3, v3 WHERE v3.c2 = t3.c2 AND t3.c2 LIKE "%00%" AND v3.c2 LIKE "%00%"; -- オリジナル SQL SELECT * FROM t1, v2 WHERE v2.c1 = t1.c2 AND t1.c2 IN (1,5,7); -- 派生 SQL SELECT * FROM t1, v2 WHERE v2.c1 = t1.c2 AND t1.c2 IN (1,5,7) AND v2.c1 IN (1,5,7);HAVING 句における MIN/MAX の導出。例:
-- オリジナル SQL SELECT * FROM t1 GROUP BY a,b,c HAVING MAX(b) > 20; -- 派生 SQL SELECT * FROM t1 WHERE b > 20 GROUP BY a,b,c; -- オリジナル SQL SELECT * FROM t1 GROUP BY a,b,c HAVING MIN(b) < 20; -- 派生 SQL SELECT * FROM t1 WHERE b < 20 GROUP BY a,b,c;
制限事項
同じタイプの比較条件が存在する場合、推移述語生成は統一されている必要があります。例:
CREATE TABLE t1(c1 INT, c2 INT); CREATE TABLE t2(c1 INT, c2 VARCHAR(64)); CREATE view v2 AS SELECT * FROM t2; SELECT * FROM v2,t1 WHERE v2.c1 > t1.c2 AND t1.c2 > v2.c2;説明サンプル SQL では、
v2.c2はVARCHAR型です。中間変数t1.c2を介して非等価関係を送信できるように見えますが、v2.c1はINT型で、v2.c2はVARCHAR型であるため、INT型のt1.c2は、異なる値メソッドを使用してv2.c1およびv2.c2と比較されます。したがって、強制的な導出は元の SQL セマンティクスに準拠していません。MIN/MAX関数の導出は、単一のMIN/MAX集計関数を持つクエリに限定されます。他の同様の集計関数が存在する場合、WHERE句の派生述語条件によってこれらの関数の結果が変更され、派生 SQL と元の SQL の間に不一致が生じる可能性があります。例:SELECT a, MIN(b), AVG(c) FROM t1 GROUP BY a HAVING MIN(b) < 20;説明サンプル SQL では、
AVG(c)とMIN(b)の 2 つの集計関数が使用されています。WHERE句にb < 20を含めるルールを適用すると、テーブルt1のスキャン中にb < 20を満たさない行が除外されます。このフィルタリングは、AVG(c)の計算には影響しません。ただし、特定のグループの場合、AVG(c)の結果値に影響を与える可能性があり、元のクエリ セマンティクスとの不一致につながります。したがって、他の集計関数の結果に影響するシナリオでは、MIN/MAXの導出はサポートされていません。
使用方法
準備
推移述語生成を利用するには、loose_predicate_deduce_mode パラメーターを構成して、述語の導出を有効にします。構成手順については、「クラスター パラメーターとノード パラメーターの構成」をご参照ください。
パラメーター名 | レベル | 説明 |
loose_predicate_deduce_mode | グローバル | 推移述語生成機能のコントロール スイッチ。有効値:
|
MIN/MAX の導出には、個別のパラメーターは必要ありません。HAVING 句から WHERE 句への条件プッシュダウン機能を有効にすると、MIN/MAX の導出も有効になります。詳細については、「条件プッシュダウン(HAVING 句から WHERE 句へ)」をご参照ください。
例 1
-- サンプル テーブルの作成
CREATE VIEW v1
AS
SELECT c1, c2, MAX(c3) AS max_c3
, AVG(c4) AS avg_c4
FROM t2
GROUP BY c1, c2
HAVING max_c3 > 10;
EXPLAIN FORMAT = TREE SELECT * FROM v1, t1 WHERE v1.c1 >= t1.c2 AND t1.c2 = v1.c2;
EXPLAIN
-> Inner hash join (t1.c2 = v1.c2)
-> Table scan on t1 (cost=0.18 rows=10)
-> Hash
-> Table scan on v1
-> Materialize
-> Filter: (max_c3 > 10)
-> Table scan on <temporary>
-> Aggregate using temporary table
-> Filter: (t2.c1 >= t2.c2) (cost=0.75 rows=2)
-> Table scan on t2 (cost=0.75 rows=5)「条件プッシュダウン(WHERE 句から派生テーブルへ)」の前に、推移述語生成のステップを組み込みます。式 v1.c1 >= t1.c2 and t1.c2 = v1.c2 では、非等価関係と等価関係を送信することで、単一テーブル条件 v1.c1 > v1.c2 を導出できます。その後、条件 v1.c1 > v1.c2 は条件プッシュダウンによって派生テーブルにプッシュダウンされ、派生テーブル内の対応するフィールド t2.c1 >= t2.c2 に変換され、早期のデータ フィルタリングが促進されます。
例 2
SELECT a, b, ee
FROM (
SELECT b, a, MIN(c) AS ee
FROM t1
GROUP BY a, b
) dt
GROUP BY a, b
HAVING MIN(ee) < 20;
-- 派生変換後 ========>
SELECT a, b, ee
FROM (
SELECT b, a, MIN(c) AS ee
FROM t1
WHERE c < 20
GROUP BY a, b
) dt
GROUP BY a, b;
-- 次の実行計画は、MIN/MAX 派生適用後の結果も示しています
EXPLAIN FORMAT = TREE SELECT a, b, ee
FROM (
SELECT b, a, MIN(c) AS ee
FROM t1
GROUP BY a, b
) dt
GROUP BY a, b
HAVING MIN(ee) < 20;
EXPLAIN
-> Table scan on <temporary>
-> Aggregate using temporary table
-> Table scan on dt
-> Materialize
-> Table scan on <temporary>
-> Aggregate using temporary table
-> Filter: (t1.c < 20) (cost=*** rows=***)
-> Table scan on t1 (cost=*** rows=***)外部クエリでは、最初に MIN/MAX 条件を使用して条件 MIN(ee) < 20 を判断し、dt.ee < 20 を確立します。次に、この条件は派生テーブル dt にプッシュダウンされます。このテーブル内では、HAVING 条件 MIN(c) < 20 によって、MIN/MAX を介して t1.c < 20 が導出されます。この一連の変換により、フィルター条件がデータ ソースに近づき、クエリ プロセスが高速化されます。