count(0) count(1) count(索引字段) count(非索引字段)(修正)

    技术2022-07-10  130

    在自己电脑上没有很大的数据量所以在公司的测试环境进行了测试验证,不便截图

    我在一个有100多万的表中执行了

    select count(0)

    select count(1)

    select count(*)

    select count(唯一索引字段)

    select count(没有索引字段)

     

    经过执行计划比较性能:

      count(唯一索引字段)=count(0)= count(1)= count(*)>count(没有索引字段)

    count(0)和count(1)和count(*)的执行计划一样,都会走索引扫描,查询的时间接近,比较少的查询次数得出的结果差异无法对性能进行评价,执行计划判断性能是比较好的标准。

     

    count(0)将返回表格中所有存在的行的总数包括值为null的行

    count(1)会统计包括null值的所有符合条件的字段的条数。

    count(0)count(1) count(*) 都会返回null的行

    count(字段)将返回表格中除去null以外的所有行的总数(有默认值的列也会被计入)

    2020年11月11日 对前文中的错误进行一定的修订

    之前写的 count(唯一索引字段)=count(0)= count(1)= count(*)>count(没有索引字段) 是单单在我们测试库中对执行计划进行的比较的结果(在学习mysql的过程中发现了这个是有错误的)

    但是mysql对 count(*) 做过优化,执行的过程是不会吧所有字段取出来的行数进行累加的,它是单纯的进行行累加

    count(0)和count(1)相同,以count(1)举例, 这种情况是取出行(不取行内数据),然后把1放入这一行,server 层判断是不可能为空的,就对行数进行累加,同时也解释了为什么能取出来所有字段都为null的行

    对于 count(主键 id) 来说,InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给 server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加。

    对于 count(字段) 来说:如果这个“字段”是定义为 not null 的话,一行行地从记录里面读出这个字段,判断不能为 null,按行累加;如果这个“字段”定义允许为 null,那么执行的时候,判断到有可能是 null,还要把值取出来再判断一下,不是 null 才累加。

    所以在统计查询的时候按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(*),所以我建议你,尽量使用 count(*)。

     

     

     

     

     

     

     

     

     

      

    Processed: 0.009, SQL: 9