count(*) 这么慢,我该怎么办?


mysql常用的两种引擎 Mysalm和InnoDB
Mysalm引擎把一个表的总行数存在磁盘上,因此执行 count(*) 可以立即返回,效率很高
InnoDB引擎需要把数据行一行一行读出来,统计计数。(由于多版本并发控制MVCC,InnoDB对于返回多少条记录是不确定的,可见的行才能够用于计算“基于这个查询”的表的总行数)
 
count(*)的优化,因为主键索引的叶子节点是真实数据,普通索引的叶子节点是主键值,所以普通索引树比主键索引树小很多。对于 count(*)操作,遍历哪个索引树得到的结果都是一样的。因此,MySQL优化器会找到最小那颗树遍历。
 
不同 count()的用法(InnoDB)
  • count(*) mysql做了优化
  • count(1) 遍历整张表,不取值,对于返回的每一行,放一个数字“1”进去,判断到不可能为空,按行累加。
  • count(字段) 如果该字段 设置为notNull ,一行行的从记录里面取出该字段,判断不能为Null,按行累加。
  • count(字段) 如果该字段 设置为允许Null,一行行从记录取该字段,发现可能为Null,再次判断是否为Null,不是Null累加。
结论:效率排序 count(*)≈count(1)>count(主键 id)>count(字段)
 
InnoDB count(*)解决方案
  1. 计数存入Redis中,缺点不能完全保证数据一致性,会有数据丢失风险。
  2. 计数存入MySQL,利用事务保证数据一致性。
SQL
  • 作者:低调做个路人 (扫码联系作者)
  • 发表时间:2020-08-25 18:30:46
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 评论