MySQL面试题(1):count
InnoDB 和 MyISAM 的 count(*) 有何不同
- MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个数(无where条件)
- InnoDB 执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数
为什么 InnoDB 不跟 MyISAM 一样,也把数字存起来呢?
因为即使是在同一个时刻的多个查询,由于多版本并发控制(MVCC)的原因,InnoDB 表“应该返回多少行”也是不确定的。
InnoDB count(*)、count(主键 id)、count(字段) 和 count(1) 这几个用法的性能差别,为什么
- count(字段)<count(主键 id)<count(1)≈count(*)
- count(*) 专门做了优化,不取值。
- count(1) 不取值。server 层对于返回的每一行,放一个数字“1”进去
- 对于 count(主键 id) 来说,InnoDB 引擎会把每一行的 id 值都取出来,返回给 server 层。server 层按行累加。
- 对于 count(字段) 来说,需要先判断字段是否可以为空,再判断值是否为空
count(*) 操作 innoDB 做了哪些优化
B+树只有叶子结点上有数据,全部遍历其实就是对叶子结点的链表进行遍历。此时如果遍历主键索引树,由于其叶子结点上存放的是完整的行信息,对于一个数据页而言其行密度会比较小,最终导致要扫描的数据页较多,进而IO开销也比较大。如果遍历第二索引树,其叶子结点只存放主键信息,其数据页的行密度比较大,最终扫描的数据页较少,节省了IO开销。