1.基本语法
EXPLAIN [ ANALYZE ] [ VERBOSE ] sql语句
各参数含义:
analyze:执行语句并显示真正的运行时间和其它统计信息,会真正执行SQL语句;
verbose:显示额外的信息,尤其是计划树中每个节点的字段列表,schema识别表和函数名称。总是打印统计数据中显示的每个触发器的名字;
costs:包括每个计划节点的启动成本预估和总成本的消耗,也包括行数和行宽度的预估;
buffers:使用信息,特别包括共享块命中、读、脏和写的次数,本地块命中、读、脏和写,临时块读和写的次数;
timing:在输出中包含实际启动时间和每个节点花费的时间,重复读系统块在某些系统上会显著的减缓查询的速度,只在ANALYZE也启用的时候使用;
format:声明输出格式,可以为TEXT, XML, JSON 或 YAML,默认text;
2.分情况举例说明
a. 简单查询,无where:
seq scan 代表全表顺序扫描,括号参数从左至右依次是:
- 评估开始消耗:这是可以开始输出前的时间,比如排序节点的排序的时间;
- 评估总消耗:假设查询从执行到结束的时间。有时父节点可能停止这个过程,比如LIMIT子句;
- 评估查询节点的输出行数,假设该节点执行结束;
- 评估查询节点的输出行的平均字节数;
b.简单查询,有where:
查询节点增加了“filter”条件,意味着查询节点为扫描的每一行数据增加条件检查,只输入符合条件数据。评估的输出记录数因为where子句变少了,但是扫描的数据还是10000条,所以消耗没有减少,反而增加了一点cup的计算时间。
这个查询实际输出的记录数是7000,但是评估是个近似值,多次运行可能略有差别,这中情况可以通过ANALYZE命令改善
c. 简单查询,where条件添加索引:
查询器规划分两步:首先子查询节点查看索引找到符合条件索引,然后外层查询节点将这些记录从表中提取出来,其中Bitmap是系统排序的一种机制;
d.简单查询,where条件,有的字段有索引,有的字段没有索引:
stringu1不是索引列 stringu1='xxx'减少了输出记录数的评估,但没有减少时间消耗,因为系统还是要查询相同数量的记录;
e. 简单查询,where条件,不同字段是独立索引:
如果在不同的字段上有独立的索引,规划器可能选择使用AND或者OR组合索引,不在使用filter;
f.多表联合查询
这个规划中有一个内连接的节点和两个子节点。节点摘要行的缩进反映了规划树的结构。最外层是一个连接节点,子节点是一个Bitmap扫描。外部节点位图扫描的消耗和记录数如同我们使用SELECT...WHERE unique1 < 10,因为这时t1.unique2 = t2.unique2还没关联。接下来为每一个从外部节点得到的记录运行内部查询节点。这里外部节点得到的数据的t1.unique2值是可用的
g.anaylze多表联合查询
使用ANALYZE选项可以检查规划器评估的准确性,EXPLAIN实际运行查询,显示真实的返回记录数和运行每个规划节点的时间
实际时间(actual time)的值是已毫秒为单位的实际时间,cost是评估的消耗,是个虚拟单位时间,所以他们看起来不匹配。
通常最重要的是看评估的记录数是否和实际得到的记录数接近。在这个例子里评估数完全和实际一样,但这种情况很少出现
此外EXPLAIN ANALYZE还有一些额外信息:
排序节点(Sort)显示排序类型(一般是在内存还是在磁盘)和使用多少内存,哈希节点(Hash)显示哈希桶和批数以及使用内存的峰值
另一种额外信息是过滤条件过滤掉的记录数: