mysql count聚合函数性能

count(*)、count(主键id) 和 count(1) 都表示返回满足条件的结果集的总行数;
而count(字段),则表示返回满足条件的数据行里面,参数“字段”不为 NULL 的总个数。

性能差别

  1. server 层要什么就给什么;
  2. InnoDB 只给必要的值;
  3. 现在的优化器只优化了 count(*) 的语义为“取行数”,其他“显而易见”的优化并没有
    做。

对于 count(主键 id) 来说,InnoDB 引擎会遍历整张表,把每一行的 id 值都取出来,返回给
server 层。server 层拿到 id 后,判断是不可能为空的,就按行累加。
对于 count(1) 来说,InnoDB 引擎遍历整张表,但不取值。server 层对于返回的每一行,放一
个数字“1”进去,判断是不可能为空的,按行累加。
单看这两个用法的差别的话,你能对比出来,count(1) 执行得要比 count(主键 id) 快。因为从
引擎返回 id 会涉及到解析数据行,以及拷贝字段值的操作。
对于 count(字段) 来说:

  1. 如果这个“字段”是定义为 not null 的话,一行行地从记录里面读出这个字段,判断不能
    为 null,按行累加;
  2. 如果这个“字段”定义允许为 null,那么执行的时候,判断到有可能是 null,还要把值取出
    来再判断一下,不是 null 才累加。
    也就是前面的第一条原则,server 层要什么字段,InnoDB 就返回什么字段。
    但是 count() 是例外,并不会把全部字段取出来,而是专门做了优化,不取值。count() 肯定
    不是 null,按行累加。
    看到这里,你一定会说,优化器就不能自己判断一下吗,主键 id 肯定非空啊,为什么不能按照
    count() 来处理,多么简单的优化啊。
    当然,MySQL 专门针对这个语句进行优化,也不是不可以。但是这种需要专门优化的情况太多
    了,而且 MySQL 已经优化过 count(
    ) 了,你直接使用这种用法就可以了。
    所以结论是:按照效率排序的话,count(字段)<count(主键 id)<count(1)≈count(),所以我
    建议你,尽量使用 count(
    )
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章