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となります。 |