count(*) 的实现方式
你首先要明确的是,在不同的 MySQL 引擎中,count(*) 有不同的实现方式。
MyISAM 引擎把一个表的总行数存在了磁盘上,因此执行 count(*) 的时候会直接返回这个数,效率很高;
而 InnoDB 引擎就麻烦了,它执行 count(*) 的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。
这里需要注意的是,我们在这篇文章里讨论的是没有过滤条件的 count(*),如果加了 where 条件的话,MyISAM 表也是不能返回得这么快的。
show table status 命令显示的行数也不能直接使用,是采样估计的。
小结:
1、MyISAM 表虽然 count(*) 很快,但是不支持事务;
2、show table status 命令虽然返回很快,但是不准确;
3、InnoDB 表直接 count(*) 会遍历全表,虽然结果准确,但会导致性能问题。
不同的 count 用法:
按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*),所以我建议你,尽量使用 count(*)。