Hologres的EXPLAIN和EXPLAIN ANALYZE简介
文章目录
- 一、执行计划
- 1、概念简介
- 2、使用方式
- ①、EXPLAIN
- ②、EXPLAIN ANALYZE
- 二、算子解读
- 1、SCAN
- 2、Index Scan和 Index Seek
- 3、Filter
- 4、Decode
- 5、Redistribution
- 6、Join
- 7、Broadcast
- 8、Shard prune和Shards selected
- 9、ExecuteExternalSQL
- 10、Aggregate
- 11、Sort
- 12、Limit
- 13、Append
- 14、Exchange
- 15、Forward
- 16、Project
一、执行计划
1、概念简介
EXPLAIN:代表优化器QO根据SQL特征预估的SQL执行计划,并非实际的执行计划,对SQL的运行有一定参考意义。
EXPLAIN ANALYZE:代表SQL真实的运行计划,相比EXPLAIN会包含更多的实际运行信息,能准确的反映出SQL的执行算子和算子耗时,可以根据算子耗时去做针对性的SQL优化。
2、使用方式
①、EXPLAIN
EXPLAIN <sql>;示例:
EXPLAIN SELECTl_returnflag,l_linestatus,sum(l_quantity) AS sum_qty,sum(l_extendedprice) AS sum_base_price,sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,avg(l_quantity) AS avg_qty,avg(l_extendedprice) AS avg_price,avg(l_discount) AS avg_disc,count(*) AS count_order
FROMlineitem
WHEREl_shipdate <= date '1998-12-01' - interval '120' day
GROUP BYl_returnflag,l_linestatus
ORDER BYl_returnflag,l_linestatus;
解释说明: 执行计划需要从下往上看,每个箭头(->)代表一个节点,每个子节点会返回使用的算子,以及预估的行数等。
②、EXPLAIN ANALYZE
EXPLAIN ANALYZE <sql>;示例:
EXPLAIN ANALYZE SELECTl_returnflag,l_linestatus,sum(l_quantity) AS sum_qty,sum(l_extendedprice) AS sum_base_price,sum(l_extendedprice * (1 - l_discount)) AS sum_disc_price,sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,avg(l_quantity) AS avg_qty,avg(l_extendedprice) AS avg_price,avg(l_discount) AS avg_disc,count(*) AS count_order
FROMlineitem
WHEREl_shipdate <= date '1998-12-01' - interval '120' day
GROUP BYl_returnflag,l_linestatus
ORDER BYl_returnflag,l_linestatus;
解释说明: EXPLAIN ANALYZE的执行结果反映的是真实执行路径,其结果是一个由多个算子组成的树状结构,会反映出每个阶段每个算子的详细执行信息。EXPLAIN ANALYZE的结果主要包括Query Plan、Advice、Cost耗时、Resource资源消耗情况。
二、算子解读
详情点击参考
1、SCAN
Seq Scan表示顺序地从表中读取数据,会进行全表扫描。
2、Index Scan和 Index Seek
如果扫描表有命中索引,根据表的存储格式(行存或列存) Hologres在底层使用的索引也不同。
1、Clustering_index:表示使用了列存表的索引(例如segment 、clustering等),只要查询命中索引就会使用Clustering_index。
2、Index Seek(又名pk_index):表示使用了行存表的索引,主要是主键索引。
3、Filter
Filter代表将数据根据SQL条件进行过滤,一般会跟随seq scan on table一起,是seq scan的子节点,表示扫描表时是否有过滤,以及过滤条件是否命中索引。
主要包括: Filter、Segment Filter、Cluster Filter、Bitmap Filter、Join Filter
4、Decode
Decode表示对数据进行解码或者编码,以加速text等文本类数据的计算。
5、Redistribution
Redistribution表示数据通过哈希分布或者随机分布,查询时shuffle到一个或者多个shard。
如果出现redistribution,则说明没有利用local join的能力,导致查询性能不佳。没有利用有两种情况
1.distribution key设置不合理
2.对应的key(如join key、group by key)涉及到表达式时
6、Join
多表关联(Join)根据SQL的书写方式又分为hash join、nested loop和merge join。
Hash Join: hash join是指两个表或者多表join时,基于其中一个表(一般为小表)在内存中构建一个hash表,并把join的列值进行hash计算后放进hash表中,之后逐行的读取另外的表,计算出其hash值并在hash表中查找,最终返回匹配的数据。当出现hash join时,我们需要额外关注join表中的小表(数据量较小的表)是否是做了hash表,可以通过如下几种方式查看:
1、执行计划中,有hash字样的表是hash表。
2、执行计划中,从下往上看,最下面的表则是hash表。
Nested Loop Join和Materialize:
Nested Loop代表嵌套循环连接,多表关联时,先从一张表中读取数据,成为外层表,再将外层驱动表的每条数据遍历另外的表(即内层表),然后内外层表嵌套循环进行Join,相当于计算笛卡尔积。在执行计划中第一内层表通常有Materialize算子。
7、Broadcast
Broadcast指通过广播的方式将数据分发到各个shard,通常用在Broadcast Join的场景中,一般是小表join大表。
8、Shard prune和Shards selected
Shard prune: 表示获取Shard的方式,包括:
lazaily:根据节点中的Shard ID先标记对应的Shard,在后续计算时选择对应的Shard。
eagerly:根据命中的Shard选择对应的Shard,不需要的Shard则不需要选择。
优化器会根据执行计划来自动匹配Shard prume的方式,无需手动调节。
Shards selected: Shards selected表示选中了多少个Shard,例如1 out of 20表示在20个Shard中选中了一个Shard。
9、ExecuteExternalSQL
Hologres的计算引擎会分为HQE、PQE、SQE等,其中PQE是原生Postgres引擎,部分Hologres自研引擎HQE还没有支持的算子和函数,会通过PQE执行,相比于HQE,PQE的执行效率会更低。当我们在执行计划中看到有ExecuteExternalSQL算子,说明有函数或者算子走了PQE。
10、Aggregate
Aggregate代表将数据聚合,可以是一个聚合函数或者多个聚合函数的组合。
- GroupAggregate:表示数据已经按照group by进行了预排序。
- HashAggregate(最常见):表示数据先进行hash计算,然后通过hash值分发至不同的shard进行聚合,最终通过Gather算子聚合。
- 多阶段HashAggregate:数据是在shard中按照文件存储的,文件有不同的层级,当数据量多时,聚合的阶段也会分为多个阶段。主要的子算子包括:
Partial HashAggregate:文件和shard内的聚合。
Final HashAggregate:多个shard上的数据聚合在一起。
11、Sort
sort表示将数据按顺序排序(升序ASC或者降序DESC),通常是order by子句的结果。
调优建议:如果order by的数据量较大,将会消耗较多的资源,需要尽量避免大数据量的排序查询。
12、Limit
limit表示SQL最终允许返回的数据行数。并不代表实际计算中扫描的行数
13、Append
子查询的结果合并,通常为Union All操作。
14、Exchange
Shard内的数据交换。无需过多关注。
15、Forward
Forward代表将算子的数据在HQE与PQE或者SQE之间传输,一般是HQE+PQE或者HQE+SQE的组合会出现。
16、Project
Project一般表示子查询与外层查询的映射关系,无需过多关注。