今天组里的同学在查找慢sql的时候发现一个问题,sql如下:

explain
select
count(*)
from
isv_item_poi_0

执行得到结果,扫描了222120行数据,这个时候我们加上 where id > 0, sql如下:

explain
select
count(*)
from
isv_item_poi_0
where 
id > 0

执行得到结果,扫描了111060行数据,同统计全表有多少行,为什么加上where条件扫描的行数变少了呢。 id是主键自增索引,都是大于0的,由于是统计是全表有多少行,那自然的想法也是应该扫描所有的行数,怎么会因为加上id > 0行数就少了一半呢。

观察两个expalin的结果可以发现使用的索引不同,这里是因为相同数量的二级索引记录可以比聚簇索引记录占用更少的存储空间,所以二级索引树比聚簇索引树小,这样遍历二级索引的 I/O 成本比遍历聚簇索引的 I/O 成本小,因此「优化器」优先选择的是二级索引。

这个解释并不能很好的说明结果,但这里可以判断在count(*)的时候查询二级索引b+树的时候不需要回表,可是这并不能说明为什么扫描行数正好是主键索引的一半的事实, 这里我们考虑到是不是联合索引的问题,因为是两个key所以正好是一半。 使用了三个key的联合索引,也正好是主键索引的一半。