摘要:本文主要介绍如何详细解读GaussDB(DWS)产生的分布式执行计划,从计划中发现性能调优点。

前言

执行计划(又称解释计划)是数据库执行SQL语句的具体步骤,例如通过索引还是全表扫描访问表中的数据,连接查询的实现方式和连接的顺序等。如果 SQL 语句性能不够理想,我们首先应该查看它的执行计划。本文主要介绍如何详细解读GaussDB(DWS)产生的分布式执行计划,从计划中发现性能调优点。

1、执行算子介绍

要读懂执行计划,首先要知道数据库执行算子的概念:

下面重点介绍下基于sharing nothing的分布式计划中最重要的一类算子——STREAM算子

三种类型的stream算子

1) Gather Stream (N:1) – 每个源结点都将其数据发送给目标结点

2) Redistribute Stream (N:N) – 每个源节点将其数据根据连接条件计算Hash值,根据重新计算的Hash值进行分布,发给对应的目标节点

3) Broadcast Stream (1:N) – 由一个源节点将其数据发给N个目标节点

其中1)主要用于CN与DN间的数据交换,2)与3)主要用于DN间的数据交换

2、EXPLAIN用法

SQL执行计划是一个节点数,显示执一条SQL语句执行时的详细步骤。每一个步骤是一个数据库运算符,也叫作一个执行算子。使用explain命令可以查看优化器为每个查询生成的具体执行计划。

1) EXPLAIN的语法

其中,option中COSTS与NODES的默认值为ON,其他参数默认为OFF。

说明:

a) EXPLAIN + QUERY并不会真正执行,只会将计划打印出来,指定option中的ANALYZE可以进行实际执行

b) PERFORMANCE 选项默认会将所有的选项置为ON,即显示所有的执行信息。

c) CPU/BUFFER/DETAIL 选项依赖于ANALYZE,只有ANALYZE置为ON的时候,才能使用这几个选项。

d) DETAIL选项用来控制输出,DETAIL 置为ON时,会显示各个DN上具体的执行信息;DATAIL 置为OFF时,显示所有DN的汇总信息,即最大最小值信息。

2) EXPLAIN显示格式

GaussDB中提供了两种显示格式(normal/pretty),通过设置参数explain_perf_mode进行控制。其中,normal格式为默认的显示格式。

normal格式如下:

pretty格式如下:

改进后的显示格式,层次清晰,计划包含了plan node id,性能分析会更加简单直接。

使用之前可以使用show explain_perf_mode;来查看当前数据库使用的显示风格。

同时可以使用set explain_perf_mode=pretty/normal;来设置输出的格式。

3、示例计划解读(每个算子资源消耗、耗时等等)

1) 四中常见类型计划

建表语句:

a) FQS计划,完全下推,下发query

两表JOIN,且其连接条件为各表的分布列,在关闭stream算子的情况下,CN会直接将该语句发送至各DN执行,最后结果在CN汇总。

b) 非FQS计划,部分语句下推

两表JOIN,且连接条件中包含非分布列,此时在关闭stream算子的情况下,CN会将基表扫描语句下发至各DN,然后在CN上进行JOIN。

c) Stream计划,DN之间无数据交换

两表JOIN,且连接条件为各表的分布列,因此各DN无需数据交换。CN生成stream计划后,将除Gather Stream的计划下发给DN执行,在各个DN上进行基表 扫描,并进行哈希连接后,发送给CN。

d) Stream计划,DN之间存在数据交换

两表JOIN,且连接条件包含非分布列,在开启stream算子的情况下,会生成stream计划,其DN间存在数据交换。此时对于tt02表,会在各DN进行基表扫描,扫描后会通过Redistribute Stream算子,按照JOIN条件中的tt02.c1进行哈希计算后重新发送给各DN,然后在各DN上做JOIN,最后汇总到CN。

2) explain performance详解

a) 执行计划

•id:执行算子节点编号。

•operation:具体的执行节点算子名称。

•A-time:各DN相应算子执行时间,[]中左侧为最小值,右侧为最大值,包括下层算子执行时间。

•A-rows:相应算子输出的全局总行数。

•E-rows:每个算子估算的输出行数。

•Peak Memory:各DN相应算子消耗内存峰值,[]中左侧为最小值,右侧为最大值。

•E-memory:DN上每个算子估算的内存使用量,只有DN上执行的算子会显示。某些场景会在估算的内存使用量后使用括号显示该算子在内存源充足下可以自动扩展的内存上限。

•E-width:每个算子输出元组的估算宽度。

•E-costs:每个算子估算的执行代价。

b) 谓词过滤

显示对应执行算子节点的过滤条件

c) 内存使用

主要显示CN的最大内存用量、DN最大内存用量、各算子的最大内存用量、各算子预估内存用量、Stream线程的启动以及收发时间。

d) Targetlist Information

各个算子对应的输出目标列信息。

e) DN信息

各算子的执行时间、Buffer、CPU信息

f) 自定义信息

CN与DN之间的建连信息、DN与DN之间的建连信息。

g) 汇总信息

    • DN执行器开始时间,[min_node_name, max_node_name] : [min_time, max_time]
    • DN执行器结束时间,[min_node_name, max_node_name] : [min_time, max_time]
    • Remote query poll time:接收结果时用于poll等待的时间
    • CN执行器开始、运行及结束时间
    • 网络流量,stream算子发送的数据量
    • 优化器执行期时间
    • 查询ID
    • 总执行时间

h) 执行时间介绍

每个算子的执行信息都包含三个部分:

其中:

    • dn_6001_6002/dn_6003_6004 表示具体执行的节点信息,括号中的信息是实际的执行信息
    • actual time=0.013..2290.971 表示实际的执行时间

第一个数字表示执行时进入当前算子到输出第一条数据所花费的时间

第二个数字为输出所有数据的总执行时间

注意:在整个计划中,除了叶子节点的执行时间是算子本身的执行时间,其余算子的执行时间均包含子节点的执行时间。

在该计划中,7号节点和9号节点为叶子节点,其余节点均为非叶子简介。1号节点时顶层节点,所以该节点的执行时间就可以作为整个查询的执行时间。

    • rows=2001550 表示当前算子输出数据为2001550行;
    • loops=1 表示当前算子的只执行了一次,而对于分区表的扫描(7号节点)来说:

该层扫描算子的loops为7,对于分区表,每一个分区表的扫描就是一次完整的扫描操作,当切换到下一个分区的时候,又是一次新的查询操作,查询该表定义如下:

Inventory表有7个分区,所以就执行了7次表扫描操作,因此loops=7。

i) CPU信息介绍

每个算子执行的过程都有CPU信息,其中cyc代表的是CPU的周期数,ex cyc表示的是当前算子的周期数,不包含其子节点;inc cyc是包含子节点的周期数;ex row是当前算子输出的数据行数;ex c/r则是ex cyc/ex row得到的每条数据所用的平均周期数。

j) Buffer信息介绍

buffers显示缓冲区信息,包括共享块和临时块的读和写。

共享块包含表和索引,临时块在排序和物化中使用的磁盘块。上层节点显示出来的块数据包含了其所有子节点使用的块数。

Buffers涉及的参数有两种,分别为:shared和temp,及shared hit/read/dirtied/written以及temp read/write

Hit blocks:代表从磁盘里面读到的数据块数

Dirtied blocks:代表当前查询中被修改了的并且此前未被修改的数据块数

Written blocks:代表当前线程将shared bufer里被修改的数据写回到磁盘的块数

k) 执行内存

其中:

Peak Memory:5KB 表示当前算子实际执行时使用的峰值内存;

Estimate Memory:1024MB 表示预估的内存,为优化器给出的预估值。

l) 其他执行信息

(1)sort 算子,会显示排序信息

Sort Method代表排序的方法,包括quicksort(快排)和disksort(外排)。快排即内存够用时,所有的排序操作均在内存中完成,外排说明当前可用内存不足,需要下盘。

(2)hashjoin算子

Buckets:代表hash表中实际使用的桶的个数

Batches:代表hashjoin中实际分块的数量。如果Batches=1,则说明所有的数据全在内存中,没有下盘操作;反之则说明有下盘操作,Batches - 1代表临时文件的个数。

Memory Usage:就是hashjoin中内存的使用情况

(3)hashagg算子

如果发生数据下盘,会有File Num:512信息,显示临时文件的个数。

(4)stream算子

stream算子的会统计当前算子处理数据的字节数,其从子线程获取数据的时间(poll time)以及处理数据的时间(Deserialize Time)。

stream算子的子节点会统计发送端的时间信息,如下:

发送时间Send time,排队时间Wait Quota time, OS发送时间以及数据处理的时间。

3) explain 调优示例

一个查询语句要经过多个算子步骤才会输出最终的结果。由于个别算子耗时过长导致整体查询性能下降的情况比较常见。这些算子是整个查询的瓶颈算子。通用的优化手段是EXPLAIN ANALYZE/PERFORMANCE命令查看执行过程的瓶颈算子,然后进行针对性优化。

基表扫描时,对于点查或者范围扫描等过滤大量数据的查询,如果使用SeqScan全表扫描会比较耗时,可以在条件列上建立索引选择IndexScan进行索引扫描提升扫描效率。如下示例:

上述例子中,全表扫描返回3360条数据,过滤掉大量数据,在sssolddate_sk列上建立索引后,使用IndexScan扫描效率显著提高,从960毫秒提升到8毫秒。

结语:

在调优过程中,熟练使用explain并能分析各部分数据结果是非常重要的。本文中仅仅介绍了大多数字段的含义以及根据explain结果进行调优的一个小示例,还可以与plan hint结合使用找出执行的最佳路径,也可以定位倾斜程度等等。

点击关注,第一时间了解华为云新鲜技术~

详解GaussDB(DWS) explain分布式执行计划的更多相关文章

  1. 详解GaussDB(DWS) 资源监控

    摘要:本文主要着重介绍资源池资源监控以及用户资源监控. 本文分享自华为云社区<GaussDB(DWS)资源监控之用户.队列资源监控>,作者: 一只菜菜鸟. GaussDB(DWS)资源监控 ...

  2. MySQL 使用explain查看执行计划

    使用explain查看执行计划, 下面是针对这两条语句进行分析,其查询结果是一样的. EXPLAIN select n.id,n.title from info n inner join info_t ...

  3. hive高阶1--sql和hive语句执行顺序、explain查看执行计划、group by生成MR

    hive语句执行顺序 msyql语句执行顺序 代码写的顺序: select ... from... where.... group by... having... order by.. 或者 from ...

  4. SQL优化 MySQL版 -分析explain SQL执行计划与笛卡尔积

    SQL优化 MySQL版 -分析explain SQL执行计划 作者 Stanley 罗昊 [转载请注明出处和署名,谢谢!] 首先我们先创建一个数据库,数据库中分别写三张表来存储数据; course: ...

  5. SQL优化 MySQL版 -分析explain SQL执行计划与Type级别详解

    type索引类型.类型 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:看此文章前,需要有一定的Mysql基础或观看上一篇文章,该文章传送门: https://www.cnblo ...

  6. 详解MySQL中EXPLAIN解释命令

    Explain 结果解读与实践   基于 MySQL 5.0.67 ,存储引擎 MyISAM .   注:单独一行的"%%"及"`"表示分隔内容,就象分开“第一 ...

  7. 索引使用,分析初探。(explain分析执行计划,以及强制使用force index)

    促使这次探索的初衷还是因为要对一个定时脚本性能进行优化. 脚本有两个指定状态分别是status, latest_process_status,和一个超期时间expire_time进行限制. 按照我以前 ...

  8. KafkaProducer Sender 线程详解(含详细的执行流程图)

    目录 1.Sender 线程详解 2.RecordAccumulator 核心方法详解 温馨提示:本文基于 Kafka 2.2.1 版本. 上文 <源码分析 Kafka 消息发送流程> 已 ...

  9. SQL优化 MySQL版 -分析explain SQL执行计划与Extra

    Extra 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 注:此文章必须有一定的Mysql基础,或观看执行计划入门篇传送门: https:.html 终于总结到哦SQK执行计划的最 ...

随机推荐

  1. Linux 系统中环境变量/etc/profile、/etc/bashrc、~/.bashrc的区别

      /etc/profile./etc/bashrc.~/.bashrc的区别   1> etc目录下存放系统管理和配置文件 (系统配置) etc/profile:  profile为所有的用户 ...

  2. 我的Python自学之路-002 字典的知识

    '''字典是python中唯一的验证类型,采用键值对(key-value)的形式存储数据.python对key进行哈希函数运算.根据计算的结果决定value的存储地址.所以字典是无序存储的.且key必 ...

  3. hystrix熔断器之线程池

    隔离 Hystrix有两种隔离方式:信号量和线程池. 线程池隔离:对每个command创建一个自己的线程池,执行调用.通过线程池隔离来保证不同调用不会相互干扰和每一个调用的并发限制. 信号量隔热:对每 ...

  4. leetcode560题解【前缀和+哈希】

    leetcode560.和为K的子数组 题目链接 算法 前缀和+哈希 时间复杂度O(n). 在解决这道题前需要先清楚,一个和为k的子数组即为一对前缀和的差值. 1.我们假设有这么一个子数组[i,j]满 ...

  5. 详尽的 Elasticsearch7.X 安装及集群搭建教程

    为了更好的阅读体验,欢迎访问 原文阅读链接 简介 首先引用 Elasticsearch (下文简称 ES)官网的一段描述: Elasticsearch 是一个分布式.RESTful 风格的搜索和数据分 ...

  6. 每天一个dos命令-net.

    Rem:关于net命令相关的常用实例(如果cmd中执行net相关命令,报错:Access is denied. 可以右键cmd,以管理员身份运行即可!) 1.创建一个新账号:net user ifsf ...

  7. 趣图:大佬如何解决bug的

    Bug 变 Feature, 这招简直太帅了!   扩展阅读 趣图:我说自己菜 vs 大佬说自己菜 趣图:公司实习生找 Bug 趣图:国内一些大平台的推荐算法 趣图:开发和测试是如何对待代码的 趣图: ...

  8. Tomcat 中 catalina.out、catalina.log、localhost.log 和 access_log 的区别

    打开 Tomcat 安装目录中的 log 文件夹,我们可以看到很多日志文件,这篇文章就来介绍下这些日记文件的具体区别. catalina.out 日志 catalina.out 日志文件是 Tomca ...

  9. spring+springmvc+mybatis+shiro

    创建maven框架https://blog.csdn.net/Ajax_mt/article/details/78549119 具体下边 https://blog.csdn.net/w2222288/ ...

  10. Layman 分享到朋友圈或发送给朋友

    *主要是介绍如何在网页中实现发送给朋友和分享到朋友圈时内容参数自定义的功能 微信JS接口 1.微信JS-SDK是微信公众平台面向网页开发者提供的基于微信内的网页开发工具包; 通过使用微信JS-SDK, ...