count()函数
count()是一个聚合函数,对于返回的结果集,一行行地判断,如果count函数的参数不是NULL,累计值就加1,否则不加。最后返回累计值。
count(*)、count(1)、count(主键id)和count(字段)区别
count(*)、count(1)和count(主键id)都表示返回满足条件的结果集的总行数;而count(字段)则表示返回满足条件的数据行里面,参数“字段”不为NULL的总个数。
count(主键id)与count(1)
对于count(主键id)来说,InnoDB引擎会遍历整张表,把每一行的id值都取出来,返回给server层。server层拿到id后,判断id不为NULL的,就按行累加
对于count(1)来说,InnoDB引擎遍历整张表,但不取值。server层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加
总的来说,count(1)执行得要比count(主键id)快一些。因为从引擎返回id会涉及到解析数据行,以及拷贝字段值的操作
count(字段)
count(非空字段)
如果这个“字段”定义为notnull,一行行地从记录里面读出这个字段,判断不可能为null,按行累加。
注意:count(非空字段)与count(主键id)的效率是一样的
count(可空字段)
如果这个“字段”定义为可为null,那么执行的时候,判断到有可能是null,还要把值取出来再判断一下,不是null才累加
count(*)
count(*)是例外,优化器专门对其做了优化,并不会把全部字段取出来,而是直接按行累加。
执行效率
按照效率排序,count(可空字段)<count(非空字段)=count(主键id)<count(1)≈count(*),所以尽量使用count(*)就行了
执行效果上:
count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL。
count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL。
count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数,即某个字段值为NULL时,不统计。
执行效率上:
列名为主键,count(列名)会比count(1)快。
列名不为主键,count(1)会比count(列名)快。
如果表多个列并且没有主键,则count(1)的执行效率优于count(*)。
如果有主键,则selectcount(主键)的执行效率是最优的。
如果表只有一个字段,则selectcount(*)最优。
|