一、执行计划

1.执行计划是什么:

一条sql以最快最低消耗获取出所需数据的一个执行过程。

SQL 是一种“描述型”语言。与“过程型”语言不同,用户在使用 SQL 时,只描述了“要做什么”,而不是“怎么做”。因此,数据库在接收到 SQL 查询时,必须为其生成一个“执行计划”。执行计划可以告诉我们SQL如何使用索引,连接查询的执行顺序,查询的数据行数等

执行计划本质上是由物理操作符构成的一棵执行树。物理操作符一般对应一个关系操作,如表扫描、联接、聚合、排序等。执行计划通过将不同的物理操作符按照一定的先后顺序组织在一棵执行树中,最终完成该 SQL 查询。

2.执行计划的作用:

在sql优化过程中,查看sql是如何执行的,究竟要涉及多少行、使用哪些索引、运行时间等

 

二、查看执行计划sql语法

1.语法



EXPLAIN [ ( option [, ...] ) ] statement
EXPLAIN [ ANALYZE ] [ VERBOSE ] statement

这里 option可以是:

ANALYZE [ boolean ]
VERBOSE [ boolean ]
COSTS [ boolean ]
BUFFERS [ boolean ]
TIMING [ boolean ]
FORMAT { TEXT | XML | JSON | YAML }



  • analyze:执行语句并显示真正的运行时间和其它统计信息,会真正执行SQL语句;
  • verbose:显示额外的信息,尤其是计划树中每个节点的字段列表,schema识别表和函数名称。总是打印统计数据中显示的每个触发器的名字;
  • costs:包括每个计划节点的启动成本预估和总成本的消耗,也包括行数和行宽度的预估;
  • buffers:使用信息,特别包括共享块命中、读、脏和写的次数,本地块命中、读、脏和写,临时块读和写的次数;
  • timing:在输出中包含实际启动时间和每个节点花费的时间,重复读系统块在某些系统上会显著的减缓查询的速度,只在ANALYZE也启用的时候使用;
  • format:声明输出格式,可以为TEXT、XML、JSON 或 YAML,默认 text;

2.示例

2.1. EXPLAIN 



EXPLAIN SELECT * FROM t2


执行结果:



Seq Scan on t2  (cost=0.00..11.10 rows=110 width=670)


2.2 EXPLAIN ANALYZE:



EXPLAIN ANALYZE SELECT * FROM t2


执行结果:



Seq Scan on t2  (cost=0.00..11.10 rows=110 width=670) (actual time=0.009..0.011 rows=14 loops=1)
Planning Time: 0.091 ms
Execution Time: 0.055 ms


2.3. EXPLAIN ANALYZE VERBOSE



EXPLAIN ANALYZE VERBOSE SELECT * FROM t2


执行结果:



Seq Scan on public.t2  (cost=0.00..11.10 rows=110 width=670) (actual time=0.029..0.030 rows=14 loops=1)
Output: id, name, age, address
Planning Time: 0.038 ms
Execution Time: 0.040 ms


三、执行计划的解读

1.扫描方式

1.1顺序扫描Seq Scan


顺序扫描实际上就是全表扫描,没有任何可用索引或者不适合走索引的情况下的一种查询行为



2.索引扫描IndexScan(包含回表过程)


通过访问索引获得元组位置指针后再访问表数据本身,index scan实际上是包含了通过索引键值查找,然后“回表”的过程,这个执行计划或者字面上,都没有体现出来。



EXPLAIN ANALYZE SELECT * FROM t2 WHERE id =3


执行结果 :



Index Scan using t2_pkey on t2  (cost=0.14..8.16 rows=1 width=670) (actual time=0.015..0.016 rows=1 loops=1)
Index Cond: (id = 3)
Planning Time: 0.066 ms
Execution Time: 0.032 ms


说明:

  回表:就是扫描索引获取到需要查询的行地址信息后,根据行地址信息,定位到对应行并获取这些行数据的过程

3. Index Only Scan


索引scan不需要回表:




EXPLAIN ANALYZE SELECT id FROM t2 WHERE id =3


执行结果:



Index Only Scan using t2_pkey on t2  (cost=0.14..8.16 rows=1 width=4) (actual time=0.039..0.041 rows=1 loops=1)
Index Cond: (id = 3)
Heap Fetches: 1
Planning Time: 0.059 ms
Execution Time: 0.054 ms


说明:

  不需要回表的原因:相对于上面的sql语句,这里只查询了id, 而id正好就是查询时要扫描的索引的字段,索引中已经包含了id值,索引不需要再回表获取行数据。


4.位图索引扫描Bitmap Index Scan

 

2.表与表之间的连接处理方式

包括三种:loop join,merge join,hash join这三种join方式

1.loop join