count(*)很“慢”?
实现方式
1.MyISAM引擎把一个表的总行数存在磁盘上,执行count(*)的时候会直接返回这个数。
2.InnoDB时,则需要一行一行的从引擎里面读出来,然后累计计数。
对于count(*)这样的操作,MySQL优化器会找到最小的那棵树来遍历。再保证逻辑正确的前提下,尽量减少扫描的数据量,是数据库系统设计的通用法则之一。
show table status命令是采用采样估计来估算的,不能直接使用。
解决办法
1.通过缓存保存计数。
将计数保存在缓存系统中的方式,还不只是丢失更新的问题。即使Redis 正常工作,这个值还是逻辑上不精确的。
2.在数据库保存计数
由于事务的可见性,可保证逻辑上的数据的一致性。
不同count的用法
count()函数的参数不是NULL,累计值就加1,否则不加。最后返回累计值。
count(*),count(主键),count(1),count(字段)的区别
count(主键id),遍历每一行把每一行的id值取出来,返回给id层,server层拿到id后,判断不为空,则按行累加。
count(1),server层对于返回的每一行,放一个数字“1”进去,按行累加。
count(字段):一行一行的从记录里面读取字段
1.定义为not null的话,一行行的从记录里面读出这个字段,判断不能为null,按行累加。
2.定义为允许null,那么执行的时候,判断到有可能是null,还要把值取出来判断一下,不是null才累加。
count(*),并不会把全部字段取出来,而是专门做了优化,不取值。
按照效率排序的话:count(字段)<count(主键 id)<count(1)≈count(*)。