更新时间:2025-03-13 GMT+08:00

Materialize

算子说明

Materialize算子用于缓存子节点返回的结果,对子查询结果进行保存。对于需要重复多次扫描的子节点(特别是扫描结果每次都相同时)可以减少执行代价。

典型场景

  • 当查询语句涉及子查询,需要多次查询同一批数据时,优化器会选择Materialize算子来缓存子查询的结果,从而大大减少扫描的执行时间。子查询常存在于关键字包括IN、ANY、ALL、EXISTS等子句中。
  • 连接操作选择Nest Loop作为连接算子。

示例

示例:带ALL的子查询。

--数据准备。 
gaussdb=# DROP TABLE IF EXISTS student;
gaussdb=# CREATE TABLE student(id integer, class_id integer, grade number); 
CREATE TABLE 
gaussdb=# CREATE TABLE class_table(class_id integer); 
CREATE TABLE 
gaussdb=# INSERT INTO student VALUES(generate_series(1,50), 1, floor(100 * random())); 
INSERT 0 50 
gaussdb=# INSERT INTO student VALUES(generate_series(51,100), 2, floor(100 * random())); 
INSERT 0 50 
gaussdb=# INSERT INTO student VALUES(generate_series(101,150), 3, floor(100 * random())); 
INSERT 0 50 
gaussdb=# INSERT INTO student VALUES(generate_series(151,200), 3, floor(100 * random())); 
INSERT 0 50 
gaussdb=# INSERT INTO class_table VALUES(1),(2),(3),(4); 
INSERT 0 4

-- 执行结果。 
gaussdb=# EXPLAIN SELECT * FROM student WHERE class_id >= all (SELECT class_id FROM class_table); 
                                      QUERY PLAN
---------------------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=0.38..100.67 rows=10 width=40)
   Node/s: All datanodes
   ->  Seq Scan on student  (cost=0.00..100.11 rows=10 width=40)
         Filter: (SubPlan 1)
         SubPlan 1
           ->  Materialize  (cost=0.00..13.28 rows=80 width=4)
                 ->  Streaming(type: BROADCAST)  (cost=0.00..13.18 rows=40 width=4)
                       Spawn on: All datanodes
                       ->  Seq Scan on class_table  (cost=0.00..13.13 rows=20 width=4)
(9 rows)

--删除。
gaussdb=# DROP TABLE IF EXISTS student,class_table;