提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
该结论来自诸葛老师:mysql的innodb
count(1)>count(非主键)=count(*)>count(主键)
1 前提
使用的是5.7以上的mysql的innoddb的索引的表。
假设该表有一个主键索引 id ,还有一个非主键索引 name 。
2 分析
- count(1):使用非主键索引,而且不获取叶子节点id 的具体值,效率最高。
- count(非主键):使用非主键索引,获取叶子节点id 的具体值,比count(1)效率弱那么一丢丢,基本可以忽略不计。但是如果该字段可以为空,那么count(非主键)是不统计值为null的记录的。
- count(*):使用非主键索引,获取叶子节点id 的具体值,和count(非主键)效率差不多,而且不会漏掉Null的记录。
- count(主键):在低版本中用的是主键聚簇索引,由于聚簇索引带所有记录数据,比较大,加载就慢点,效率就比使用非聚簇索引低一点。但是最晚在5.7版本时,mysql做了优化, count(主键)用的也是非聚簇索引。
3 总结
- 在5.7及以上版本的Mysql中,这四种select count的效率相差不大。
- count(非主键)会漏统计值为null的记录
- 诸葛老师建议用select(*),本人建议select(1)。老师也说了差不多。
4 补充
- 如果是myIsam索引,count(*)效率极高,因为总记录数被mysql存在磁盘上,不需要计算。
- 如果是innodb索引,需要实时计算。但如果只要个大概总记录数的话,可以用
show table status
,或者用redis(但也不可靠,很难保证表操作和redis操作的事务一致性),或者在数据库里专门搞个表,记录各表的记录数。