如何查看SQL的执行计划
Posted 瀚高实验室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何查看SQL的执行计划相关的知识,希望对你有一定的参考价值。
目录
环境
文档用途
详细信息
环境
系统平台:N/A
版本:6.0,4.5.2,5.6.5,4.3.4.9
文档用途
本文主要用于介绍如何通过explain命令查看SQL的详细执行计划。
详细信息
一、explain命令详解
1、语法
EXPLAIN [ ( option [, ...] ) ] statement
EXPLAIN [ ANALYZE ] [ VERBOSE ] statemen
2、选项说明
option可以有以下选项
analyze:执行语句并显示真正的运行时间和其它统计信息,会真正执行SQL语句;
verbose:显示额外的信息,尤其是计划树中每个节点的字段列表,schema识别表和函数名称。总是打印统计数据中显示的每个触发器的名字;
costs:包括每个计划节点的启动成本预估和总成本的消耗,也包括行数和行宽度的预估;
buffers:使用信息,特别包括共享块命中、读、脏和写的次数,本地块命中、读、脏和写,临时块读和写的次数;
timing:在输出中包含实际启动时间和每个节点花费的时间,重复读系统块在某些系统上会显著的减缓查询的速度,只在ANALYZE也启用的时候使用;
format:声明输出格式,可以为TEXT、XML、JSON 或 YAML,默认 text;
二、explain输出详解
1、计划解读
a=> explain analyze select * from pgbench_accounts ; QUERY PLAN Seq Scan on pgbench_accounts (cost=0.00..2688.00 rows=100000 width=97) (actual time=0.267..34.302 rows=100000 loops=1) Planning Time: 0.165 ms Execution Time: 46.280 ms |
cost=0.00..2688.00,0.00代表启动成本;2688.00代表返回所有数据的成本;rows=100000表示返回多少行;width=97,表示每行平均宽度(以字节计算);actual time=0.267..34.302,实际花费的时间;loops=1,循环的次数;
Planning Time,生成执行计划的时间;
Execution Time,执行执行计划的时间。
2、输出参数详细说明
- cost:第一个数字表示启动的成本,也就是返回第一行需要多少cost值;第二个数字表示返回所有的数据的成本。默认cost值如下
- 顺序扫描一个数据块,cost值定为1
- 随机扫描一个数据块,cost值定为4
- 处理一个数据行的 CPU,cost为0.01
- 处理一个索引行的 CPU,cost为0.005
- 每个操作符的CPU代价为0.0025
- rows:表示会返回多少行
- width:表示每行平均宽度为多少字节
- buffers
- shared hit:表示在共享内存中直接读到 多少个块,
- read:表示从磁盘读了多少块
- written:写磁盘多少块
执行计划含义
- Seq Scan:全表扫描
- Index Scan:索引扫描
- Bitmap Heap Scan:位图扫描
- Filter:条件过滤
- Nestloop Join:嵌套循环连接,是在两个表做连接时,内表被外表驱动,外表返回的每一行都要在内表中检索找到与它匹配的行,因此整个查询返回的结果集不能太大,要把返回子集较小的表作为外表,而且在内表的连接字段上要有索引,否则会很慢。执行过程:
- 确定一个驱动表(outer table),另一个表为inner table
- 驱动表中的每一行与inner 表中的相应记录 JOIN 类似一个嵌套的循环
- Hash Join:使用两个表中较小的表,并利用连接键在内存中建立散列表,然后扫描较大的表并探测散列表,找出与散列表匹配的行。适用于较小的表可以完全放入内存中的情况。如果表很大,不能完全放入内存,优化器会将它分割成若干不同的分区,把不能放入内存的部分写入磁盘的临时段。
- Merge Join:如果源数据上有索引,或者结果已经被排过序,在执行排序合并连接时就不需要排序了,Merge Join 的性能会优于散列连接。
3、解读原则
①从下往上读
②从右至左读
③开启时间消耗是输出开始前的时间例如排序的时间
④消耗包括磁盘检索页,cpu时间
⑤注意,每一步的cost包括上一步的
⑥重要的是,explain 不是真正的执行一次查询 只是得到查询执行的计划和估计的花费
4、其他举例说明
下面是一个hash,hash join例子: |
首先在表pg_namespace上做了一次顺序扫描,之后进行hash运算形成一个hash表,之后再pg_class表上进行顺序扫描,再进行hash join操作,hash join操作的条件为"outer".relnamespace = "inner".oid。
以上是关于如何查看SQL的执行计划的主要内容,如果未能解决你的问题,请参考以下文章