更新时间:2026-07-28 GMT+08:00
分享

操作指导

前提条件

本节将结合示例展示优化器基本的计划选择过程,使用如下建表语句:

gaussdb=# CREATE TABLE t1(a INT, b INT, c INT, d INT);
NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default.
HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.
CREATE TABLE
gaussdb=# CREATE INDEX idx_t1_a ON t1(a);
CREATE INDEX
gaussdb=# CREATE INDEX idx_t1_b ON t1(b);
CREATE INDEX
gaussdb=# INSERT INTO t1 (a, b, c) VALUES (generate_series(1, 10000), generate_series(1, 5000), floor(random()*10));
INSERT 0 10000
gaussdb=# ANALYZE t1;
ANALYZE
gaussdb=# CREATE TABLE t2(a INT, b INT, c INT, d INT);
NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default.
HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.
CREATE TABLE
gaussdb=# CREATE INDEX idx_t2_a ON t2(a);
CREATE INDEX
gaussdb=# CREATE INDEX idx_t2_b ON t2(b);
CREATE INDEX
gaussdb=# INSERT INTO t2 (a, b, c) VALUES (generate_series(1, 10000), generate_series(1, 5000), floor(random()*10));
INSERT 0 10000
gaussdb=# ANALYZE t2;
ANALYZE
gaussdb=# SET explain_perf_mode=normal;
SET
gaussdb=# SET enable_hashjoin=on;
SET
gaussdb=# SET enable_mergejoin=on;
SET

操作示例

下面示例通过对同一个SQL的过滤条件取不同的常量值来展示代价模型对CBO优化器进行计划选择时的影响。首先,执行如下SQL语句并查看其选择的计划(过滤条件取值:t2.b <= 100):

gaussdb=# EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.a = t2.c AND t2.b <= 100;
                                          QUERY PLAN
----------------------------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=13.95..16.88 rows=100 width=32)
   Node/s: All datanodes
   ->  Merge Join  (cost=11.89..12.76 rows=100 width=32)
         Merge Cond: (t1.a = t2.c)
         ->  Index Scan using idx_t1_a on t1  (cost=0.00..44.47 rows=5000 width=16)
         ->  Sort  (cost=11.84..12.09 rows=100 width=16)
               Sort Key: t2.c
               ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..8.52 rows=100 width=16)
                     Spawn on: All datanodes
                     ->  Index Scan using idx_t2_b on t2  (cost=0.00..3.73 rows=100 width=16)
                           Index Cond: (b <= 100)
(11 rows)

当过滤条件取值变为 t2.b <= 3000时,优化器选择生成计划如下所示:

gaussdb=# EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.a = t2.c AND t2.b <= 3000;
                                    QUERY PLAN
-----------------------------------------------------------------------------------
 Streaming (type: GATHER)  (cost=49.51..299.97 rows=3000 width=32)
   Node/s: All datanodes
   ->  Hash Join  (cost=45.51..174.97 rows=3000 width=32)
         Hash Cond: (t2.c = t1.a)
         ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..115.24 rows=3000 width=16)
               Spawn on: All datanodes
               ->  Seq Scan on t2  (cost=0.00..28.84 rows=3000 width=16)
                     Filter: (b <= 3000)
         ->  Hash  (cost=24.67..24.67 rows=5001 width=16)
               ->  Seq Scan on t1  (cost=0.00..24.67 rows=5000 width=16)
(10 rows)

上述SQL中,t1表与t2表做INNER JOIN,连接条件为t1.a = t2.c AND t2.b <=100, 其中连接条件t1.a = t2.c不变,当t2.b <= ? 常量值取值100时执行计划选择Merge Join路径,利用t1表和t2表上的索引条件提升执行性能;但当常量值变为3000时,执行计划变成了Hash Join路径,其表明随着优化器会根据连接表的不同、约束条件的变化选择合适的查询计划,从而在实际生产环境中能够有效减少人工调优的场景,提升效率。

后置操作

gaussdb=# DROP TABLE t1;
DROP TABLE
gaussdb=# DROP TABLE t2;
DROP TABLE
gaussdb=# RESET explain_perf_mode;
RESET

相关文档