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

执行计划

以如下SQL语句为例:

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 | ->  Hash Join (2,3)      |  23091 |      16 | 58.353..355.674
  2 |    ->  Seq Scan on t1    |   2149 |       8 | 0.000..31.490
  3 |    ->  Hash              |   2149 |       8 | 31.490..31.490
  4 |       ->  Seq Scan on t2 |   2149 |       8 | 0.000..31.490
(4 rows)

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

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

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

    • 第二层:Hash

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

    • 第三层:Seq Scan on t1

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

    • 第四层:Hash Join

      join算子,主要作用是将t1表和t2表的数据通过hash join的方式连接,并输出结果数据。