MATERIAL 算子用于物化下层算子输出的数据。

OceanBase 数据库以流式数据执行计划,但有时算子需要等待下层算子输出所有数据后才能够开始执行,所以需要在下方添加一个 MATERIAL 算子物化所有的数据。或者在子计划需要重复执行的时候,使用 MATERIAL 算子可以避免重复执行。

如下示例中,t1 表与 t2 表执行 NESTED LOOP JOIN 运算时,右表需要重复扫描,可以在右表有一个 MATERIAL 算子,保存 t2 表的所有数据。

obclient>CREATE TABLE t1(c1 INT, c2 INT, c3 INT);Query OK, 0 rows affected (0.12 sec)obclient>CREATE TABLE t2(c1 INT ,c2 INT ,c3 INT);Query OK, 0 rows affected (0.12 sec)obclient>EXPLAIN SELECT  /*+ORDERED USE_NL(T2)*/* FROM t1,t2          WHERE t1.c1=t2.c1\G;*************************** 1. row ***************************Query Plan: ===========================================|ID|OPERATOR        |NAME|EST. ROWS|COST  |-------------------------------------------|0 |NESTED-LOOP JOIN|    |2970     |277377||1 | TABLE SCAN     |t1  |3        |37    ||2 | MATERIAL       |    |100000   |176342||3 |  TABLE SCAN    |t2  |100000   |70683 |===========================================Outputs & filters: -------------------------------------  0 - output([t1.c1], [t1.c2], [t1.c3], [t2.c1], [t2.c2], [t2.c3]), filter(nil),       conds([t1.c1 = t2.c1]), nl_params_(nil)  1 - output([t1.c1], [t1.c2], [t1.c3]), filter(nil),       access([t1.c1], [t1.c2], [t1.c3]), partitions(p0)  2 - output([t2.c1], [t2.c2], [t2.c3]), filter(nil)  3 - output([t2.c1], [t2.c2], [t2.c3]), filter(nil),       access([t2.c1], [t2.c2], [t2.c3]), partitions(p0)

上述示例中,执行计划展示中 2 号算子 MATERIAL 的功能是保存 t2 表的数据,以避免每次联接都从磁盘扫描 t2 表的数据。执行计划展示中的 outputs & filters 详细展示了 MATERIAL 算子的输出信息如下:

信息名称

含义

output

该算子输出的表达式。

其中 rownum() 表示 ROWNUM 对应的表达式。

filter

该算子上的过滤条件。

由于示例中 MATERIAL 算子没有设置 filter,所以为 nil。