1、语法:
explain (选项) statement; 例子:explain(analyze,buffers) select * from student;
2、执行例句以及解析:
-
执行动作,及其附加条件,比如索引扫描,索引条件等
-
估算成本:启动cost、总体cost
-
估计返回的行数和平均宽度
-
如果开启了Analyze选项,还会返回:
-
实际成本:启动cost、总体cost
-
实际返回的行数,节点循环执行次数
-
explain analyze select * from student where sname='ada';
QUERY PLAN
---------------------------------------------------------------
Index Scan using idx_stu on student (cost=0.14..8.15 rows=1 width=10)(actual time=0.074..0.074 rows=0 loops=1)
Index Cond: (sname = 'ada'::text)
Planning Time: 0.122 ms
Execution Time: 0.245 ms
(4 行记录)
-
执行动作:Index Scan using idx_stu on student
Index Scan:表示索引扫描
Idx_stu:使用的索引名
Student:访问的表名
整句话表示:访问student表的时候,使用的是索引扫描,扫描的索引是idx_stu。
-
估算成本:(cost=0.14..8.15 rows=1 width=10)
Cost=0.14..81.5:第一个数0.14表示启动成本,也就是说返回第一行需要多少cost。第二个数值81.5表示返回所有的数据的成本。这两个数值用..分开。
Rows=1:表示该查询会返回1行记录。
Width=10:表示每行平均宽度为10字节。
需要注意的是:在执行计划里,每一步的cost值都传给了上一层,也就是说每一个cost值代表的是在此步以下所有操作的代价总和。启动成本是第一行输出开始前的成本,比如进行排序的成本。
-
实际成本:(actual time=0.074..0.074 rows=0 loops=1)
Actural time=0.074..0.074:表示实际的启动时间为0.074,实际的运行时间也为0.074。
Rows=0:表示实际查询返回了0行记录(没有查询到)。
Loops=1:表示该索引扫描只执行了1次。
这行信息为带有Analyze的explain语句特有。可以看出实际成本跟估算成本会有一定的偏差。那是因为估算成本是优化器根据统计信息估算出来的一个结果,而有时统计信息并不完全能够反映真实的情况。
为了让统计信息更准确,可以运行Analyze命令来更新整个数据库、某张表或者某个字段的统计信息,然后再次执行explain将得到一个更好的结果。
-
索引条件:Index Cond: (sname = 'ada'::text)
该句表示当前执行的索引扫描(Index Scan)使用的索引条件为:sname = 'ada'::text
-
计划和执行时间:Planning Time: 0.122 ms, Execution Time: 0.245 ms
这行信息为带有Analyze的explain语句特有。表示生成执行计划用时0.122ms,真正执行查询用时0.245ms。
3.索引扫描类型:
-
顺序扫描(Seq scan)
-
索引扫描(Index scan)
-
位图扫描(Bitmap scan)
-
TID扫描(TID scan)
-
覆盖索引扫描(Index only scan)
由于其他的在mysql都学过,这里就着重讲一下Bitmap Scan;
先看看kingbase官方文档的描述:
bitmap扫描是Bitmap Index Scan和Bitmap Heap Scan的组合。
先通过Bitmap Index Scan索引扫描,在内存中创建一个位图表,每一个bit表示一个与过滤条件有关的页面。此页面有可能有数据为1,不可能为0。
然后再通过Bitmap Heap Scan表扫描, 在内存中创建好的位图表指针对应的页面进行顺序扫描,排除不符合的记录,返回需要的结果。
Bitmap的执行:
(1)首先数据库对每一个索引的所有页面会进行查询并生产一个bitmap串;
(2)bitmap串的每一个bit位代表了索引的所有页面,而‘1’代表该页面存在符合的数据
(3)所有的bitmap串进行“&”操作,就能得到最后的Bitmap串,然后执行Recheck Cond回到相应的页面来查询相应的数据。例子如下:
bill=# create index idx_t11 on t1 using btree(c1);
CREATE INDEX
bill=# create index idx_t12 on t1 using btree(c2);
CREATE INDEX
bill=# create index idx_t13 on t1 using btree(c3);
CREATE INDEX
bill=# explain select * from t1 where c1 =10 and c2 =20 and c3 = 30;
QUERY PLAN
-----------------------------------------------------------------------------
Bitmap Heap Scan on t1 (cost=3.31..4.62 rows=1 width=12)
Recheck Cond: ((c3 = 30) AND (c2 = 20))
Filter: (c1 = 10)
-> BitmapAnd (cost=3.31..3.31 rows=1 width=0)
-> Bitmap Index Scan on idx_t13 (cost=0.00..1.53 rows=10 width=0)
Index Cond: (c3 = 30)
-> Bitmap Index Scan on idx_t12 (cost=0.00..1.53 rows=10 width=0)
Index Cond: (c2 = 20)
(8 rows)
+---------------------------------------------+
|100000000001000000010000000000000111100000000| bitmap 1
|000001000001000100010000000001000010000000010| bitmap 2
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|000000000001000000010000000000000010000000000| Combined bitmap
+-----------+-------+--------------+----------+
| | |
v v v
Used to scan the heap only for matching pages:
+---------------------------------------------+
|___________X_______X______________X__________|
+---------------------------------------------+
使用范围:很明显,这个适合多个条件的and、or操作
参考:4.2. 阅读执行计划 — KingbaseES产品手册
PostgreSQL中的bitmap scan解析_bitmap heap scan on_foucus、的博客-CSDN博客