更新时间:2025-05-29 GMT+08:00

执行计划

以如下SQL语句为例,本节示例都以pretty模式说明:

1
2
3
4
5
gaussdb=# DROP TABLE IF EXISTS t1;
gaussdb=# DROP TABLE IF EXISTS t2;
gaussdb=# CREATE TABLE t1 (c1 int, c2 int);
gaussdb=# CREATE TABLE t2 (c1 int, c2 int);
gaussdb=# SET explain_perf_mode = pretty;
执行EXPLAIN的输出为:
gaussdb=# EXPLAIN SELECT * FROM t1,t2 WHERE t1.c1 = t2.c2;
 id |                operation                | E-rows | E-width | E-costs
----+-----------------------------------------+--------+---------+---------
  1 | ->  Streaming (type: GATHER)            |     20 |      16 | 28.69
  2 |    ->  Hash Join (3,5)                  |     20 |      16 | 27.75
  3 |       ->  Streaming(type: REDISTRIBUTE) |     20 |       8 | 14.31
  4 |          ->  Seq Scan on t2             |     20 |       8 | 13.13
  5 |       ->  Hash                          |     21 |       8 | 13.13
  6 |          ->  Seq Scan on t1             |     20 |       8 | 13.13
(6 rows)

 Predicate Information (identified by plan id)
-----------------------------------------------
   2 --Hash Join (3,5)
         Hash Cond: (t2.c2 = t1.c1)
(2 rows)

--删除表。
gaussdb=# DROP TABLE t1,t2;
  • 执行计划字段解读(横向):
    • id:执行算子节点编号。
    • operation:具体的执行节点算子名称。
    • E-rows:每个算子估算的输出行数。
    • E-width:每个算子输出元组的估算宽度。
    • E-costs:每个算子估算的执行代价。
      • E-costs是优化器根据成本参数定义的单位来衡量的,习惯上以磁盘页面顺序抓取为1个单位, 其它开销参数将参照它来设置。
      • 每个节点的开销(E-costs值)包括它的所有子节点的开销。
      • 开销只反映了优化器关心的东西,并没有把结果行传递给客户端的时间考虑进去。虽然这个时间可能在实际的总时间里占据相当重要的分量,但是被优化器忽略了,因为它无法通过修改规划来改变。
  • 执行计划层级解读(纵向),计划树是自底向上的,pretty模式下每层算子以"->"缩进。最底层一般是扫描算子:
    • 算子id-4和id-6是最底层的扫描算子:
      1. Seq Scan on t1

        表扫描算子,用Seq Scan的方式扫描表t1。这一层的作用是把表t1的数据从buffer或者磁盘上读上来输送给上层节点参与hash join计算。

      2. Seq Scan on t2

        表扫描算子,用Seq Scan的方式扫描表t2。这一层的作用是把表t2的数据从buffer或者磁盘上读上来输送给上层节点参与计算。

    • 第二层:Hash

      Hash算子,作用是把下层计算输送上来的算子计算hash值生成hash表,为后续hash join操作做数据准备。

    • 第二层:Streaming(type: REDISTRIBUTE)

      Streaming是一个特殊的算子,它实现了分布式架构的核心数据shuffle功能,Streaming(type: REDISTRIBUTE):作用是DN根据选定的列把数据重分布到所有的DN,这里该算子的作用是根据join列将t2的数据重分布到各个DN节点上准备和t1join。关于Streaming算子会在后续算子详解中做具体介绍。

    • 第三层:Hash Join (3,5)

      Hash join算子,作用是将t1表和t2表的数据通过hash join的方式连接,并输出结果数据,其中(3,5)指id为3的算子的结果和id为5的算子的结果做连接

    • 第四层:Streaming (type: GATHER)

      Streaming (type: GATHER):作用是CN从DN收集数据。