相信每个人在写代码时都有遇到过要获取MYSQL表里数据行数的情况,多数人获取数据表行数时都用COUNT(*),但同时也流传了不少其他方式,比如说COUNT(1)、COUNT(主键)、COUNT(字段)。到底哪种方式MYSQL执行起来更快也是众说纷纭,其实之前我也不知道到底哪个执行起来快,到底谁说的对(笑哭)。好在最近在认真学习极客时间的MySQL专栏,其中专门有一节是对这个问题的讨论,看完后也是解除了长久以来的疑惑。

文章中都是针对MySQL的InnoDB引擎展开讨论的,MyISAM引擎是把一个表的总行数记录在了磁盘里,查询时效率很高(如果加了where条件也不能直接从磁盘返回)。而InnoDB由于多版本并发控制(MVCC)的原因,即使时同一时刻的查询InnoDB表应该"返回多少行"也是不确定的,比如假设表t中有10000行数据:

时刻 会话A 会话B 会话C
T1 begin;
T2 select count(*) from t;
T3 insert into t (插入一行);
T4 begin;
T5 insert into t (插入一行);
T6 select count(*) from t; (返回10000) select count(*) from t; (返回10002); select count(*) from t; (返回10001)

会话A在T1开启事务拿到一致性视图,可重复读级别下在事务中任何时刻读到数据都一样,其他事务的更新对会话A没影响所以count(*)的结果是10000,会话B在T4开启事务拿到一致性视图,T4之前会话C已经新插入了一条语句并提交(单独执行一条更新语句,InnoDB会自己启动一个事务,语句执行完马上提交)。会话B在T5插入一条新数据,在T6查询时count(*)的结果是10002(T4 begin时会话C insert语句已经提交,所以在会话B的事务中能看到这个更新)。由于会话B在T6时事务还没有提交,会话C看不到会话B的更新,所以会话C在T6时count(*)的结果是10001。

COUNT是一个聚合函数,它的功能是对返回的结果集中每一行进行判断,如果COUNT函数的参数不是NULL则累加1,否则不累加,最后返回累计值。接下来看一下每个COUNT版本的执行效率:

  • COUNT(主键ID) InnoDB遍历全表,把每一行的主键值都取出来返回给MySQL的Server层,因为主键不可能为NULL,Server层直接按行累加最后返回累计值给客户端。
  • COUNT(1) 遍历全表但不取值,Server层对返回的每一行放个数字"1"进去,按行累加。COUNT(1)比COUNT(主键)快,因为不需要取值,减少了数据传输。
  • COUNT(字段) 遍历全表,一行行从记录中读出字段值给Server层,Server层判断值不为NULL了再累加。
  • COUNT(*) MySQL专门做了优化,会找到表中最小的索引树,InnoDB普通索引树比主键索引小很多,对于COUNT(*)遍历哪个树是一样的,count(*)时MySQL不取记录值,count(*)也肯定不为NULL,Server层中直接按行累加。

所以这个版本COUNT的从低到高分别为:

COUNT(字段) < COUNT(主键) < COUNT(1)COUNT(*)

所以建议你尽量使用count(*)来获取记录行数。

另外要注意,很多人为了销量会把表的行数记录到Redis中,但这样不能保证Redis里的计数和MySQL表里的数据保持精确一致,这是两个不同的存储系统不支持分布式事务所以就无法拿到精确的一致性视图,如果为了效率把表行数单独存储那么最好存放在一个单独的MySQL表里,这样无法拿到一致性视图的问题就能解决了。

关于MySQL更详细的分析,推荐关注MySQL实战45讲

MYSQL统计行数时到底应该怎么COUNT相关推荐

  1. server sql 数据总行数_sql统计行数的语句

    求一个sql统计行数的语句 col1  col2 ------------------- A1   2010xx A2   2010cx A1   2010ddd A2   2011dfsd A3   ...

  2. Shell 统计行数(wc -l)

    wc -l:统计行数,原理就是统计了结果中的换行符数量. who:获取当前计算机的登录用户列表. 案例 # 这台电脑有几个用户登录了 $ who | wc -l 1# 当前目录下有几个文件夹 $ ls ...

  3. MySQL三种统计行数的方式比较

    t_user 表 统计结果比较,其中id字段为主键,该表没有非空字段 可以看到,平均时间下,统计一千万行,最快的为count(常数).最慢的为count(*),但相差都不是很大,就0.6 s 左右. ...

  4. excel统计行数_工程人常用的12个excel和9个wps技巧

    点击上方蓝字,记得关注我们! 搞工程的人要干的事,不只局限于在现场严格按照标准监督施工进行,还需要同时对收集到的资料进行收集整理,搞搞内业工作.然而很多人都是新上手,难免会对某些办公软件有些生涩. E ...

  5. excel统计行数_值得收藏的6个Excel函数公式(有讲解)

    收藏的Excel函数大全公式再多,几天不用也会忘记.怎么才能不忘?你需要了解公式的运行原理.小编今天不再推送一大堆函数公式,而是根据提问最多的问题,精选出6个实用的,然后详细的解释给大家. 1.计算两 ...

  6. excel统计行数_百万到亿级数据,快速统计查询

    大家好,我是dk.这是Excel神器PowerQuery实战入门系列的第3篇.往后,我会更新更多关于PQ的相关内容,有兴趣的小伙伴可以关注下. 众所周知,Excel2003版最大行数是65536行,到 ...

  7. C# StreamReader.ReadLine统计行数的问题

    要实现一个功能: 从 lua 文件中提取字符串放到 excel 中,再将 excel 给海外同事,翻译完成后,用翻译的文本替换相应中文. 整个功能并不复杂,要点有二点: 1.提取字符串,一行中文如&q ...

  8. MYSQL - 计算行数

    1. COUNT(*)计算table的行数 计算pet表中的动物 mysql> select count(*) from pet; +----------+ | count(*) | +---- ...

  9. Windows 下统计行数的命令

    大家都知道在Linux下统计文本行数可以用wc -l 命令,例如: -bash-3.2$ cat pif_install.log | wc -l       712 但在Windows下如何统计输出文 ...

最新文章

  1. 定义交货输出条件类型(Output Types)
  2. eclipse创建springboot项目_Spring Initializer+IntelliJ IDEA创建Spring Boot项目(图文)
  3. 【算法题1】上台阶问题
  4. 【pyqt5学习】——items view相关控件(list view、table view)
  5. 训练日志 2018.10.11
  6. graphics | 基础绘图系统(七)——各式各样的散点图/折线图
  7. java split 坑_Java坑锦集一 - split函数
  8. ffmpeg-20160629-git-bin.7z
  9. 生产环境sql语句调优实战第三篇
  10. 非参数统计的Python实现—— HL 检验
  11. 手把手教你用ppc手机远程控制电脑(摘自网络)
  12. 基于Flutter的m3u8下载器
  13. 人工智能研究的新前线:生成式对抗网络
  14. Python数据分析(五) —— 绘制直方图
  15. STM8 串口接收字符串问题
  16. GetLastErr返回值ErrCode的宏定义以及含义
  17. 利用UltrISO将gho文件制作可引导iso
  18. 组态中怎么使用mysql数据库,组态王写入MySQL数据库
  19. 阿拉伯数字转大写金额(支持简体和繁体)
  20. JNA实战笔记汇总(二)——JNA和C / C ++的数据类型映射(dll函数回调、结构体、指针)

热门文章

  1. Oracle START WITH ... CONNECT BY PRIOR 带条件会有重复
  2. 解决dom4j java.lang.NoClassDefFoundError: org/jaxen/JaxenException
  3. awk命令输出单引号
  4. “猫癣”集团借IE7新漏洞再掀风浪
  5. [转]Android Service Test——简单测试例子
  6. layui框架使用总结
  7. ECharts 学习笔记
  8. PHP操作MongoDB学习笔记
  9. linux 下搭建postfix服务器
  10. WSS 3.0 and MOSS 2007 SP2 发布