OceanBase SUBPLAN FILTER

2021-06-29 17:13 更新

SUBPLAN FILTER 算子用于驅(qū)動(dòng)表達(dá)式中的子查詢執(zhí)行。

OceanBase 數(shù)據(jù)庫(kù)以 NESTED-LOOP 算法執(zhí)行 SUBPLAN FILTER 算子,執(zhí)行時(shí)左邊取一行數(shù)據(jù),然后執(zhí)行右邊的子計(jì)劃。SUBPLAN FILTER 算子可以驅(qū)動(dòng)相關(guān)子查詢和非相關(guān)子查詢計(jì)算,并且兩種執(zhí)行方式不同。

驅(qū)動(dòng)非相關(guān)子查詢計(jì)算

示例 1:SUBPLAN FILTER 算子驅(qū)動(dòng)非相關(guān)子查詢計(jì)算

obclient>CREATE TABLE t1(c1 INT, c2 INT);
Query OK, 0 rows affected (0.09 sec)

obclient>CREATE TABLE t2(c1 INT, c2 INT);
Query OK, 0 rows affected (0.09 sec)

obclient>EXPLAIN SELECT /*+NO_REWRITE*/c1 FROM t1 WHERE 
        c2 > (SELECT MAX(c2) FROM t2)\G;
*************************** 1. row ***************************
Query Plan: 
| ===========================================
|ID|OPERATOR        |NAME|EST. ROWS|COST  |
-------------------------------------------
|0 |SUBPLAN FILTER  |    |33334    |167652|
|1 | TABLE SCAN     |T1  |100000   |68478 |
|2 | SCALAR GROUP BY|    |1        |85373 |
|3 |  TABLE SCAN    |T2  |100000   |66272 |
===========================================
Outputs & filters: 
-------------------------------------
  0 - output([T1.C1]), filter(nil), 
      exec_params_(nil), onetime_exprs_([subquery(1)]), init_plan_idxs_(nil)
  1 - output([T1.C1]), filter([T1.C2 > ?]), 
      access([T1.C2], [T1.C1]), partitions(p0)
  2 - output([T_FUN_MAX(T2.C2)]), filter(nil), 
      group(nil), agg_func([T_FUN_MAX(T2.C2)])
  3 - output([T2.C2]), filter(nil), 
      access([T2.C2]), partitions(p0)

上述示例中,執(zhí)行計(jì)劃展示中 0 號(hào)算子 SUBPLAN FILTER 驅(qū)動(dòng)右邊 SCALAR GROUP BY 子計(jì)劃執(zhí)行,outputs & filters 詳細(xì)列出了 SUBPLAN FILTER 算子的輸出信息如下:

信息名稱

含義

output

該算子輸出的列。

filter

該算子上的過(guò)濾條件。

由于示例中的 SUBPLAN FILTER 算子沒(méi)有設(shè)置 filter,所以為 nil。

exec_params_

右子計(jì)劃依賴左子計(jì)劃的參數(shù),執(zhí)行期由SUBPLAN FILTER 從左子計(jì)劃中獲取,傳遞給右子計(jì)劃執(zhí)行。

由于示例中 SUBPLAN FILTER 算子驅(qū)動(dòng)非相關(guān)子查詢沒(méi)有涉及該參數(shù),所以為 nil。

onetime_exprs_

計(jì)劃中只計(jì)算一次的表達(dá)式,如果右子計(jì)劃是非相關(guān)子查詢,每次重復(fù)執(zhí)行的結(jié)果都是一樣的,所以執(zhí)行一次后保存在參數(shù)集合中。

每次執(zhí)行 SUBPLAN FILTER 時(shí),可以直接從參數(shù)集獲取右子計(jì)劃的執(zhí)行結(jié)果。參數(shù) subquery(1) 表示 SUBPLAN FILTER 右邊第一個(gè)子計(jì)劃是 onetime expr。

init_plan_ids_

該算子中只需要執(zhí)行一次的子計(jì)劃。

它與 onetime_exprs_ 的區(qū)別是,init_plan_返回多行多列,onetime_expr_ 返回單行單列。

由于示例中的 SQL 查詢未設(shè)置此項(xiàng),所以為 nil。

SUBPLAN FILTER 算子驅(qū)動(dòng)非相關(guān)子查詢計(jì)算的一般執(zhí)行流程如下:

  1. SUBPLAN FILTER 在啟動(dòng)時(shí)會(huì)執(zhí)行 onetime_exprs_。

  2. 從參數(shù)中拿到右邊非相關(guān)子查詢的結(jié)果,下推 filter 到左邊計(jì)劃,執(zhí)行左邊的查詢。

  3. 輸出左邊查詢的行。

驅(qū)動(dòng)相關(guān)子查詢計(jì)算

示例 2:SUBPLAN FILTER 算子驅(qū)動(dòng)相關(guān)子查詢計(jì)算

obclient>EXPLAIN SELECT /*+NO_REWRITE*/c1 FROM t1 WHERE c2 > (SELECT 
                MAX(c2) FROM t2 WHERE t1.c1=t2.c1)\G;
*************************** 1. row ***************************
Query Plan: 
| ===============================================
|ID|OPERATOR        |NAME|EST. ROWS|COST      |
-----------------------------------------------
|0 |SUBPLAN FILTER  |    |33334    |8541203533|
|1 | TABLE SCAN     |T1  |100000   |68478     |
|2 | SCALAR GROUP BY|    |1        |85412     |
|3 |  TABLE SCAN    |T2  |990      |85222     |
===============================================
Outputs & filters: 
-------------------------------------
  0 - output([T1.C1]), filter([T1.C2 > subquery(1)]), 
      exec_params_([T1.C1]), onetime_exprs_(nil), init_plan_idxs_(nil)
  1 - output([T1.C1], [T1.C2]), filter(nil), 
      access([T1.C1], [T1.C2]), partitions(p0)
  2 - output([T_FUN_MAX(T2.C2)]), filter(nil), 
      group(nil), agg_func([T_FUN_MAX(T2.C2)])
  3 - output([T2.C2]), filter([? = T2.C1]), 
      access([T2.C1], [T2.C2]), partitions(p0)

上述示例中,執(zhí)行計(jì)劃展示中 0 號(hào)算子 SUBPLAN FILTER 驅(qū)動(dòng)右邊 SCALAR GROUP BY 子計(jì)劃執(zhí)行,outputs & filters 詳細(xì)列出了 SUBPLAN FILTER 算子的輸出信息如下:

信息名稱

含義

output

該算子輸出的列。

filter

該算子上的過(guò)濾條件。

例如,示例 2 中的 SQL 查詢過(guò)濾條件為 t1.c2 > subquery(1)。

exec_params_

右子計(jì)劃依賴左子計(jì)劃的參數(shù),執(zhí)行期由SUBPLAN FILTER 從左子計(jì)劃中獲取,傳遞給右子計(jì)劃執(zhí)行。

左邊輸出一行數(shù)據(jù)后需要下推的參數(shù),在非相關(guān)子查詢中一般沒(méi)有下推的參數(shù)。

onetime_exprs_

計(jì)劃中只計(jì)算一次的表達(dá)式,如果右子計(jì)劃是非相關(guān)子查詢,每次重復(fù)執(zhí)行的結(jié)果都是一樣的,所以執(zhí)行一次后保存在參數(shù)集合中。

每次執(zhí)行 SUBPLAN FILTER 時(shí),可以直接從參數(shù)集獲取右子計(jì)劃的執(zhí)行結(jié)果。參數(shù) subquery(1) 表示 SUBPLAN FILTER 右邊第一個(gè)子計(jì)劃是 onetime expr。

由于示例中的 SQL 查詢未設(shè)置此項(xiàng),所以為 nil。

init_plan_idxs_

該算子中只需要執(zhí)行一次的子計(jì)劃。

與 onetime_exprs_ 的區(qū)別是,init_plan_返回多行多列,onetime_expr_ 返回單行單列。

由于示例中的 SQL 查詢未設(shè)置此項(xiàng),所以為 nil。

SUBPLAN FILTER 算子驅(qū)動(dòng)相關(guān)子查詢計(jì)算的一般執(zhí)行流程如下:

  1. SUBPLAN FILTER 在啟動(dòng)時(shí)會(huì)執(zhí)行 onetime_exprs_。

  2. 執(zhí)行左邊的查詢,輸出一行后,計(jì)算相關(guān)參數(shù),下推到右邊,執(zhí)行右邊的子查詢。

  3. 執(zhí)行 filter,輸出符合條件的數(shù)據(jù)行。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)