Greenplum之explain生成执行计划和阅读执行计划
查询分析
检查性能不好的查询的查询计划,来确定可能的性能调优机会。
Greenplum数据库为每个查询设计一个 查询计划 。选择正确的查询计划来匹配查询和数据结构对好的性能是必要的。 一个查询计划定义Greenplum数据库将如何在并行执行环境中运行查询。
查询优化器使用数据库维护的数据统计信息来选择具有最低可能代价的查询计划。代价以磁盘I/O来度量,磁盘I/O用取得的磁盘页面为单位。目标是最小化计划的总执行代价。
可以用EXPLAIN命令查看一个给定查询的计划。EXPLAIN展示查询规划器对该查询计划估计的代价。例如:
1 | EXPLAIN SELECT * FROM names WHERE id=22; |
EXPLAIN ANALYZE不仅运行该语句,还会显示它的计划。这有助于判断优化器的估计与现实有多接近。例如:
1 | EXPLAIN ANALYZE SELECT * FROM names WHERE id=22; |
Note: 在Greenplum数据库中,默认的GPORCA优化器与传统查询优化器共存。GPORCA生成的EXPLAIN输出与传统查询优化器生成的输出不同。
默认情况下,Greenplum数据库会在可能时使用GPORCA来为查询生成执行计划。
当EXPLAIN ANALYZE命令使用GPORCA时,EXPLAIN计划只显示被排除的分区数。被扫描的分区不会被显示。要在segment实例 日志中显示被扫描分区的名称,可以把服务器配置参数gp_log_dynamic_partition_pruning设置为on。这个SET命令的例子启用了该参数。
1 | SET gp_log_dynamic_partition_pruning = on; |
有关GPORCA的信息,请见查询数据
阅读EXPLAIN输出
一个查询计划是一棵节点的树。计划中的每个节点表示一个操作,例如表扫描、连接、聚集或者排序。
应该从底向上阅读计划:每个节点会把行交给直接在它上面的节点。一个计划中的底层节点通常是表扫描操作:顺序的、索引的或者位图索引扫描。如果该查询要求那些行上的连接、聚集、排序或者其他操作,就会有额外的节点在扫描节点上面负责执行这些操作。最顶层的计划节点通常是Greenplum数据库的移动节点:重新分布、显式重新分布、广播或者收集移动。这些操作在查询处理时在segment实例之间移动行。
EXPLAIN 的输出对计划树中的每个节点都有一行并且为该计划节点显示基本的节点类型和下列执行代价估计:
- cost —以磁盘页面获取为单位度量。1.0等于一次顺序磁盘页面读取。第一个估计是得到第一行的启动代价,第二个估计是得到所有行的总代价。总代价总是假定所有的行都将被检索,但并不总是这样。例如,如果查询使用了LIMIT,并非所有的行都会被检索。
- rows —这个计划节点输出的总行数。这个数字通常小于被该计划节点处理或者扫描的行数,它反映了任意WHERE子句条件的估计选择度。理想情况下,最顶层节点的估计近似于该查询实际返回、更新或者删除的行数。
- width —这个计划节点输出的所有行的总字节数。
注意以下几点:
- 一个节点的代价包括其子节点的代价。最顶层计划节点有对于该计划估计的总执行代价。这就是优化器想要最小化的数字。
- 代价只反映了被查询优化器加以考虑的计划执行的某些方面。例如,代价不反映将结果行传送到客户端花费的时间。
EXPLAIN实例
下面的例子描述了如何阅读一个查询的EXPLAIN查询代价:
1 2 3 4 5 6 | EXPLAIN SELECT * FROM names WHERE name = 'Joelle'; QUERY PLAN ------------------------------------------------------------ Gather Motion 2:1 (slice1) (cost=0.00..20.88 rows=1 width=13) -> Seq Scan on 'names' (cost=0.00..20.88 rows=1 width=13) Filter: name::text ~~ 'Joelle'::text |
从底向上阅读这个计划。一开始,查询优化器顺序地扫描names表。注意WHERE子句被应用为一个filter条件。这意味着扫描操作会对它扫描的每个行检查该条件并且只输出满足该条件的行。
扫描操作的结果被传递给一个 gather motion 操作。在Greenplum数据库中,收集移动是segment实例何时把行发送给Master。在这个例子中,我们有两个Segment实例会向一个Master实例发送。这个操作工作在并行执行计划的slices 上。查询计划会被划分成slices,这样segment实例可以并行工作在查询计划的片段上。
为这个计划估计的启动代价是00.00(没有代价)而总代价是20.88次磁盘页面获取。优化器估计这个查询将返回一行。
阅读EXPLAIN ANALYZE输出
EXPLAIN ANALYZE规划并且运行语句。EXPLAIN ANALYZE计划会把实际执行代价和优化器的估计一起显示。这允许用户查看优化器的估计是否接近于实际。EXPLAIN ANALYZE也展示下列信息:
查询执行的总运行时间(以毫秒为单位)。
查询计划每个切片使用的内存,以及为整个查询语句保留的内存。
一个计划节点操作中涉及的工作者(segment实例)数量。其中只统计返回行的segment实例。
为该操作产生最多行的segment实例返回的行最大数量。如果多个segment实例产生了相等的行数,EXPLAIN ANALYZE会显示那个用了运行最长的segment实例。
本人提供Oracle(OCP、OCM)、MySQL(OCP)、PostgreSQL(PGCA、PGCE、PGCM)等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!