MySQL count(1) 真的比 count(*) 快么? 反正同事们都是这么说的,我也姑且觉得对吧,那么没有自己研究一下究竟?如果我告诉你他们一样,你信么?

有 Where 条件的 count,会根据扫码结果count 一下所有的行数,其性能更依赖于你的 Where 条件,所以文章我们仅针对没有 Where 的情况进行说明。

MyISAM 引擎会把一个表的总行数记录了下来,所以在执行 count(*) 的时候会直接返回数量,执行效率很高。在 MySQL 5.5 以后默认引擎切换为 InnoDB,InnoDB 因为增加了版本控制(MVCC)的原因,同时有多个事务访问数据并且有更新操作的时候,每个事务需要维护自己的可见性,那么每个事务查询到的行数也是不同的,所以不能缓存具体的行数,他每次都需要 count 一下所有的行数。那么 count(1) 和 count(*)有区别么?

InnoDB handles SELECT COUNT(*) and SELECT COUNT(1) operations in the same way. There is no performance difference. 这是官网的解释,直接点击阅读原文查看官文,所以两种实现其实一样,那么具体为什么一样呢?

探究这个问题首先我们需要理解 count 的含义,如下是官网给出的定义

Returns a count of the number of non-NULL values of expr in the rows retrieved by a SELECT statement. The result is a BIGINT value.

大致的解释是返回 SELECT 语句检索的行中 expr 的非 NULL 值的计数,到这里我们就明白了,首先它是一个聚合函数,然后对 SELECT 的结果集进行计数,但是需要参数不为 NULL。那么我们继续阅读官网的内容:

COUNT(*) is somewhat different in that it returns a count of the number of rows retrieved, whether or not they contain NULL values.

大致的内容是说,count(*) 不同,他不关心这个返回值是否为空都会计算他的count,因为 count(1) 中的 1 是恒真表达式,那么 count(*) 还是 count(1) 都是对所有的结果集进行 count,所以他们本质上没有什么区别。

当然这个地方 InnoDB 本身也做了一些优化,它会使用最小的二级索引来进行 count 的查询优化。如果没有二级索引才会选择聚簇索引,这样的设计单从 IO 的角度就节省了很多开销。

到这里我们明白了 count(*) 和 count(1) 本质上面其实是一样的,那么 count(column) 又是怎么回事呢?

count(column) 也是会遍历整张表,但是不同的是它会拿到 column 的值以后判断是否为空,然后再进行累加,那么如果针对主键需要解析内容,如果是二级所以需要再次根据主键获取内容,又是一次 IO 操作,所以 count(column) 的性能肯定不如前两者喽,如果按照效率比较的话:count(*)=count(1)>count(primary key)>count(column)

既然 count(*) 在查询上依赖于所有的数据集,是不是我们在设计上也需要尽量的规避全量 count 呢?通常情况我们针对可预见的 count 查询会做适当的缓存,可以是 Redis,也可以是独立的 MySQL count 表,当然无论是哪种方式我们都需要考虑一致性的问题。

最新文章

  1. AIDL使用解析
  2. [原创]kali linux下破解wifi密码以及局域网渗透
  3. OC1_点语法
  4. word project 2010破解
  5. Problem A: 小火山的跳子游戏 多校训练2(小火山专场)(周期)
  6. 使用font-size:0去掉inline-block元素之间的空隙
  7. VMWare 虚拟化 Ubuntu 64 (16.04)-- docker 无法链接 pull 镜像 ?(solved)
  8. install_driver(Oracle) failed: Can't load `.../DBD/Oracle/Oracle.so' for module DBD::Oracle
  9. shell 常用正则表达式
  10. Writing a Simple Service and Client (C++)
  11. 实验三:分别用for,while;do-while循坏语句以及递归的方法计算n!,并输出算式。
  12. zookeeper调试命令
  13. js各种特效轮播图,选项卡,放大镜,窗口拖拽,楼层跳转
  14. Apriori算法进行关联分析
  15. B1022. D进制的A+B
  16. git学习一二三一
  17. 简单ORM工具的设计和编写,自己项目中曾经用过的
  18. Spring学习笔记--构造器注入
  19. jQuery的节点操作
  20. smarty调用php函数

热门文章

  1. 在CentOS7上无人值守安装Zabbix4.2
  2. 083、Prometheus架构(2019-05-05 周日)
  3. multipart/form-data提交
  4. redis数据库如何用Django框架缓存数据
  5. mybatis捕获sql工具
  6. ubuntu apache https设置
  7. 使用parted 创建一个大于2T的分区
  8. (转)JAVA socket 进行十六进制报文交互测试
  9. TensorFlow for python学习使用
  10. openssl x.509证书