EDB(,PG)对于执行计划的解读

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> EDB(,PG)对于执行计划的解读

EDB(/PG)对于执行计划的解读

今天同事提出了一个EDB数据库中SQL语句的性能问题,碰巧最近手头的一个系统,进行了重构开发,即将投产,用的也是EDB,想必和他打交道的机会不少,确实属于小白,有待学习的地方自然不少。

关于什么是EDB,可以参考《》。

这个性能问题,还在了解处理中,但其中用到了一些知识点,比如在EDB中,如何看一条SQL的执行计划,如何了解返回的执行计划中,每一行信息的真实含义。经过雪哥推荐,这篇文章https://blog.csdn.net/ls3648098/article/details/7602136,虽然是说PG,同样适用EDB,介绍的比较清楚。

使用explain加SQL可以得到执行计划,类似于PLSQL Developer中F5,但是SQL语句未真正执行,既然是未执行,执行计划有可能就是不准的,(关于Oracle中如何获取真实执行计划,可以参考《》),

explain select distinct course_id from course where course_term = 'Fal02'; NOTICE:  QUERY PLAN: Unique  (cost=12223.09..12339.76 rows=4667 width=4)       - Sort (cost=12223.09..12223.09 rows=46666 width=4)       -  Seq Scan on course  (cost=0.00..8279.99 rows=46666 width=4)

其中,cost部分说明:

第一个数字12223.09表示启动cost,这是执行到返回第一行时需要的cost值。

第二个数字12339.76表示执行整个SQL的cost值。

执行计划读取,

  1. 从下往上读。
  2. 每一行依次代表的信息,操作类型(例如Seq Scan on course,就是查询),开启的消耗,查询总的消耗,访问的行数,访问的平均宽度。
  3. 开启时间消耗是输出开始前的时间,例如排序的时间。
  4. 消耗包括磁盘检索页,CPU时间。
  5. 每一步的cost包括上一步的。
  6. 重要的是,explain不是真正的执行一次查询,只是得到查询执行的计划和估计的花费,类似于PLSQL Developer中F5操作。

使用explain后加analyze可以通过真实执行这个SQL来获得真实的执行计划和执行时间,和Oracle执行计划相比,PG/EDB的执行计划在表述信息上,会有一些差别。

EXPLAIN ANALYZE SELECT * FROM t;
QUERY PLAN                                                 


 Seq Scan on t  (cost=0.00..4621.00 rows=300000 width=10)

                          (actual time=0.022 ..355.380 rows=300000 loops=1)  Total runtime: 696.074 ms

其中,actual time=中的第一个数字(0.022)表示返回第一行需要的时间(叫启动时间),第二个数字(355.380)表示执行这个整个SQL花费的时间。后面的rows=300000是实际的行数。

表顺序扫描由于是立即可以获得第一行,所以启动时间一般都是0,而如果是排序操作,则需要处理完所有行后才能返回第一行,所以排序操作是需要启动时间的,下表列出了哪些操作是需要启动时间的,哪些操作不是需要的:

执行计划运算类型

操作说明

是否有启动时间

Seq Scan

扫描表

无启动时间

Index Scan

索引扫描

无启动时间

Bitmap Index Scan

索引扫描

有启动时间

Bitmap Heap Scan

索引扫描

有启动时间

Subquery Scan

子查询

无启动时间

Tid Scan

ctid = …条件

无启动时间

Function Scan

函数扫描

无启动时间

Nested Loop

循环结合

无启动时间

Merge Join

合并结合

有启动时间

Hash Join

哈希结合

有启动时间

Sort

排序,ORDER BY操作

有启动时间

Hash

哈希运算

有启动时间

Result

函数扫描,和具体的表无关

无启动时间

Unique

DISTINCT,UNION操作

有启动时间

Limit

LIMIT,OFFSET操作

有启动时间

Aggregate

count, sum,avg, stddev集约函数

有启动时间

Group

GROUP BY分组操作

有启动时间

Append

UNION操作

无启动时间

Materialize

子查询

有启动时间

SetOp

INTERCECT,EXCEPT

有启动时

关于EDB,或者是说PG,还是有不少值得学习的,无论是一些操作,还是问题排查,和Oracle有区别,但一些原理上,还是可以借鉴的,需要慢慢掌握了,否则真出现问题,就容易凌乱了。

如果您觉得本文有帮助,欢迎关注转发:bisal的个人杂货铺,

EDB(/PG)对于执行计划的解读 EDB(/PG)对于执行计划的解读
本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

转载声明:转载请注明出处,本技术博客是本人原创文章

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> EDB(,PG)对于执行计划的解读


 上一篇
MySQL表名大小写问题 MySQL表名大小写问题
在Navicat中执行检索MySQL表的操作,提示此表不存在,但库中有此表, [SQL]select * from tbl;[Err] 1146 - Table ‘bisal.tbl’ doesn’t exist 问题其实不难
下一篇 
来自MOS的一篇文章,《为何在查询中索引未被使用》 来自MOS的一篇文章,《为何在查询中索引未被使用》
前两天同事咨询一个EDB上SQL语句没有使用索引的问题,EDB号称是最像Oracle的数据库,所以一些Oracle上未用索引的经验,可以借鉴一下。 下面是从MOS上找的一篇文章,《为何在查询中索引未被使用 (Doc ID 1549