##1. 实例
我们选取了customer这个表来做测试
可以看到总共四个索引
#####1.1 测试不走索引
我们从possible_keys和key可以看到没有走索引,而且type是all就证明是全表扫描;
所以这条语句是先把所以的行记录都给找出来,然后再一条条的找fisrt_name不是null的数据统计出来。
#####1.2 测试走辅助索引
我们来查询一个走索引的字段:
我们可以从type,还有后面截图没截全的部分中的key以及extral看到使用了索引来查询。
虽然我们使用辅助索引,可以直接走辅助索引的B+树,然后把所有的key给遍历拿出来已经比非索引的快很多(非索引需要拿到所有的数据,并需要从数据中把字段值给解析出来)。但是依然需要每个数据都判断下是否为null;
即使我们count主键,也是一样的道理,因为mysql并没有对于count主键做什么不一样的优化逻辑。所以还是要逐个判断是否为null。所以即使走索引,还是有性能和速度的优化空间。
#####1.3 count(1)
我们在平时的工作中可能也很经常的使用count(1),那么这个效率如何呢?
首先我们分析一下,可以发现mysql自己给我们选择了一个索引,这个索引不是主键,也不是区分度最高的,而是别的方式选择了一个索引。
注意count(1)与上面还有个不同的地方是他不会对于索引的字段判断是否为null,而是通通对于1来判断是否为null,当然不是null了。
#####1.4 count(*)
我们大多数人可能以为count(*)应该是最慢的,因为看起来好像是把数据都取出来,然后看数据是否为null来统计。但其实mysql对这个做了优化的。
在myisam的count*是直接返回数据库中记录的数据行数的会非常快,但是我们现在主流基本都是使用innodb,就是因为事务我们才选择了innodb,可是事务带来的一个问题就是并行的事务操作数据的时候可能导致表行数不准,所以在数据库中就不记录数据表行数。
然后mysql针对于count*是做了优化的,就直接返回B+树种数据的个数,不会再到server层进行null值的判断了。