89253818 2020-04-23
以下讨论是基于InnoDB引擎。
至于分析性能差别的时候,可以记住以下几个原则:
对于count(主键id)
来说,InnoDB引擎会遍历整张表,把每一行的id值都取出来,返回给server层。server层拿到id后,判断是不可能为空的,就按行累加。
对于count(1)
来说,InnoDB引擎遍历整张表,但不取值。server层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加。
单看这两个用法的差别的话,你就能对比出来,count(1)执行的要比count(主键id)快。因为从引擎返回id会涉及到解析数据行,以及拷贝字段值的操作。
对于count(字段)
来说:
但是count(*)
是例外,并不会把全部字段取出来,而是专门做了优化,不取值。count(*)肯定不是null,按行累加。
看到这里,你一定会说,优化器就不能自己判断一下吗,主键id肯定非空啊,为什么不能按照count(*)来处理,多么简单的优化啊。
当然,mysql专门针对这个语句进行优化,也不是不可以。但是这种需要专门优化的情况太多了,而且mysql已经优化过count(*)了,直接使用这种用法就可以了。
所以结论是:按照效率排序的话,count(字段) < count(主键id) < count(1) ≈ count(*)
。所以建议尽量使用count(*)
。