SUBPLAN FILTER 演算子は、ドライバー式の式内のサブクエリの実行を制御します。
OceanBaseデータベースは NESTED LOOP アルゴリズムを使用して SUBPLAN FILTER 演算子を実行します。実行時には、まず左側から1行のデータを取得し、その後右側のサブプランを実行します。SUBPLAN FILTER 演算子は、非相関サブクエリと相関サブクエリの両方を駆動することができ、その実行方法は異なります。
非相関サブクエリの計算を駆動する場合
例1:SUBPLAN FILTER 演算子が非相関サブクエリの計算を駆動する場合
obclient> CREATE TABLE t1(c1 INT, c2 INT);
Query OK, 0 rows affected
obclient> CREATE TABLE t2(c1 INT, c2 INT);
Query OK, 0 rows affected
obclient> EXPLAIN SELECT /*+NO_REWRITE*/c1 FROM t1 WHERE c2 > (SELECT MAX(c2) FROM t2);
+---------------------------------------------------------------------------------------------------+
| Query Plan |
+---------------------------------------------------------------------------------------------------+
| =================================================== |
| |ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)| |
| --------------------------------------------------- |
| |0 |SUBPLAN FILTER | |1 |5 | |
| |1 |├─TABLE FULL SCAN |t1 |1 |3 | |
| |2 |└─SCALAR GROUP BY | |1 |3 | |
| |3 | └─TABLE FULL SCAN|t2 |1 |3 | |
| =================================================== |
| Outputs & filters: |
| ------------------------------------- |
| 0 - output([t1.c1]), filter(nil), rowset=16 |
| exec_params_(nil), onetime_exprs_([subquery(1)(:0)]), init_plan_idxs_(nil), use_batch=false |
| 1 - output([t1.c1]), filter([t1.c2 > :0]), rowset=16 |
| access([t1.c2], [t1.c1]), partitions(p0) |
| is_index_back=false, is_global_index=false, filter_before_indexback[false], |
| range_key([t1.__pk_increment]), range(MIN ; MAX)always true |
| 2 - output([T_FUN_MAX(T_FUN_MAX(t2.c2))]), filter(nil), rowset=16 |
| group(nil), agg_func([T_FUN_MAX(T_FUN_MAX(t2.c2))]) |
| 3 - output([T_FUN_MAX(t2.c2)]), filter(nil), rowset=16 |
| access([t2.c2]), partitions(p0) |
| is_index_back=false, is_global_index=false, |
| range_key([t2.__pk_increment]), range(MIN ; MAX)always true, |
| pushdown_aggregation([T_FUN_MAX(t2.c2)]) |
+---------------------------------------------------------------------------------------------------+
23 rows in set
上記の例では、実行計画表示において、0番目の演算子 SUBPLAN FILTER が右側の SCALAR GROUP BY サブプランの実行を駆動しています。outputs & filters は SUBPLAN FILTER 演算子の出力情報を詳細に列挙しています。
情報名 |
意味 |
|---|---|
| output | この演算子が出力する列。 |
| filter | この演算子のフィルター条件。例の SUBPLAN FILTER 演算子では filter が設定されていないため、nil です。 |
| exec_params_ | 右サブプランが左サブプランに依存するパラメータ。実行時に SUBPLAN FILTER が左サブプランから取得し、右サブプランへ渡します。例の SUBPLAN FILTER 演算子が非相関サブクエリを駆動する場合、このパラメータは関与しないため、nil です。 |
| onetime_exprs_ | プラン内で一度だけ計算される式。右サブプランが非相関サブクエリの場合、繰り返し実行するたびに結果は同じになるため、一度実行した後、パラメータセットに保存されます。SUBPLAN FILTER を実行するたびに、パラメータセットから直接右サブプランの実行結果を取得できます。パラメータ subquery(1) は、SUBPLAN FILTER の右側の最初のサブプランが onetime expr_ であることを示しています。 |
| init_plan_idxs_ | この演算子内で一度だけ実行する必要があるサブプラン。onetime_exprs_ との違いは、init_plan_ が複数行・複数列を返すのに対し、onetime_expr_ は1行・1列を返す点です。例のSQLクエリではこの項目が設定されていないため、nil です。 |
SUBPLAN FILTER 演算子が非相関サブクエリの計算を駆動する一般的な実行フローは以下のとおりです:
SUBPLAN FILTERは起動時にonetime_exprs_を実行します。パラメータから右側の非相関サブクエリの結果を取得し、
filterを左側のプランにプッシュダウンして左側のクエリを実行します。左側のクエリの行を出力します。
相関サブクエリの計算を駆動する場合
例2:SUBPLAN FILTER 演算子が相関サブクエリの計算を駆動する場合
obclient> EXPLAIN SELECT /*+NO_REWRITE*/c1 FROM t1 WHERE c2 > (SELECT MAX(c2) FROM t2 WHERE t1.c1=t2.c1);
+---------------------------------------------------------------------------------------------+
| Query Plan |
+---------------------------------------------------------------------------------------------+
| =================================================== |
| |ID|OPERATOR |NAME|EST.ROWS|EST.TIME(us)| |
| --------------------------------------------------- |
| |0 |SUBPLAN FILTER | |1 |5 | |
| |1 |├─TABLE FULL SCAN |t1 |1 |3 | |
| |2 |└─SCALAR GROUP BY | |1 |3 | |
| |3 | └─TABLE FULL SCAN|t2 |1 |3 | |
| =================================================== |
| Outputs & filters: |
| ------------------------------------- |
| 0 - output([t1.c1]), filter([t1.c2 > subquery(1)]), rowset=16 |
| exec_params_([t1.c1(:0)]), onetime_exprs_(nil), init_plan_idxs_(nil), use_batch=false |
| 1 - output([t1.c1], [t1.c2]), filter(nil), rowset=16 |
| access([t1.c1], [t1.c2]), partitions(p0) |
| is_index_back=false, is_global_index=false, |
| range_key([t1.__pk_increment]), range(MIN ; MAX)always true |
| 2 - output([T_FUN_MAX(T_FUN_MAX(t2.c2))]), filter(nil), rowset=16 |
| group(nil), agg_func([T_FUN_MAX(T_FUN_MAX(t2.c2))]) |
| 3 - output([T_FUN_MAX(t2.c2)]), filter([:0 = t2.c1]), rowset=16 |
| access([t2.c1], [t2.c2]), partitions(p0) |
| is_index_back=false, is_global_index=false, filter_before_indexback[false], |
| range_key([t2.__pk_increment]), range(MIN ; MAX)always true, |
| pushdown_aggregation([T_FUN_MAX(t2.c2)]) |
+---------------------------------------------------------------------------------------------+
23 rows in set
上記の例では、実行計画表示において、0番目の演算子 SUBPLAN FILTER が右側の SCALAR GROUP BY サブプランの実行を駆動しています。outputs & filters は SUBPLAN FILTER 演算子の出力情報を詳細に列挙しています。
情報名 |
意味 |
|---|---|
| output | この演算子が出力する列。 |
| filter | この演算子のフィルター条件。例えば、例2のSQLクエリのフィルター条件は t1.c2 > subquery(1) です。 |
| exec_params_ | 右サブプランが左サブプランに依存するパラメータ。実行時に SUBPLAN FILTER が左サブプランから取得し、右サブプランへ渡します。左側が1行のデータを出力した後にプッシュダウンするパラメータは、非相関サブクエリでは一般的にありません。 |
| onetime_exprs_ | プラン内で一度だけ計算される式。右サブプランが非相関サブクエリの場合、繰り返し実行するたびに結果は同じになるため、一度実行した後、パラメータセットに保存されます。SUBPLAN FILTER を実行するたびに、パラメータセットから直接右サブプランの実行結果を取得できます。パラメータ subquery(1) は、SUBPLAN FILTER の右側の最初のサブプランが onetime expr_ であることを示しています。例のSQLクエリではこの項目が設定されていないため、nil です。 |
| init_plan_idxs_ | この演算子内で一度だけ実行する必要があるサブプラン。onetime_exprs_ との違いは、init_plan_ が複数行・複数列を返すのに対し、onetime_expr_ は1行・1列を返す点です。例のSQLクエリではこの項目が設定されていないため、nil です。 |
SUBPLAN FILTER 演算子によって関連するサブクエリの計算を駆動する一般的な実行フローは以下のとおりです:
SUBPLAN FILTERは起動時にonetime_exprs_を実行します。左側のクエリを実行し、1行出力した後、関連パラメータを計算して右側にプッシュダウンし、右側のサブクエリを実行します。
filterを実行し、条件に合致するデータ行を出力します。