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
obclient> CREATE TABLE t2(c1 INT ,c2 INT ,c3 INT);
Query OK, 0 rows affected
obclient> EXPLAIN SELECT /*+ORDERED USE_NL(T2)*/* FROM t1,t2 WHERE t1.c1=t2.c1;
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 | この演算子が出力する式です。 |
| filter | この演算子のフィルター条件です。例では MATERIAL 演算子に filter が設定されていないため、nil となります。 |