zoukankan      html  css  js  c++  java
  • MySQL中count(字段) ,count(主键 id) ,count(1)和count(*)的区别

    注:下面的讨论和结论是基于 InnoDB 引擎的。

    首先要弄清楚 count() 的语义。count() 是一个聚合函数,对于返回的结果集,一行行地判断,如果 count 函数的参数不是 NULL,累计值就加 1,否则不加。最后返回累计值。

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

    至于分析性能差别的时候,记住这么几个原则:

    • server 层要什么就给什么;

    • InnoDB 只给必要的值;

    • 现在的优化器只优化了 count(*) 的语义为“取行数”,其他“显而易见”的优化并没有做。

    count(可空字段)

    扫描全表,读到server层,判断字段可空,拿出该字段所有值,判断每一个值是否为空,不为空则累加

    count(非空字段)与count(主键 id)

    扫描全表,读到server层,判断字段不可空,按行累加。

    count(1)

    扫描全表,但不取值,server层收到的每一行都是1,判断不可能是null,按值累加。

    注意:count(1)执行速度比count(主键 id)快的原因:从引擎返回 id 会涉及到解析数据行,以及拷贝字段值的操作。

    count(*)

    MySQL 执行count(*)在优化器做了专门优化。因为count(*)返回的行一定不是空。扫描全表,但是不取值,按行累加。

    看到这里,你会说优化器就不能自己判断一下吗,主键 id 肯定是非空的,为什么不能按照 count(*) 来处理,多么简单的优化。当然 MySQL 专门针对这个语句进行优化也不是不可以。但是这种需要专门优化的情况太多了,而且 MySQL 已经优化过 count(*) 了,你直接使用这种语句就可以了。

    性能对比结论

    count(可空字段) < count(非空字段) = count(主键 id) < count(1) ≈ count(*)

    赞赏码

    非学,无以致疑;非问,无以广识

  • 相关阅读:
    2018 ACM 网络选拔赛 徐州赛区
    2018 ACM 网络选拔赛 焦作赛区
    2018 ACM 网络选拔赛 沈阳赛区
    poj 2289 网络流 and 二分查找
    poj 2446 二分图最大匹配
    poj 1469 二分图最大匹配
    poj 3249 拓扑排序 and 动态规划
    poj 3687 拓扑排序
    poj 2585 拓扑排序
    poj 1094 拓扑排序
  • 原文地址:https://www.cnblogs.com/lxwphp/p/15452780.html
Copyright © 2011-2022 走看看