MySQL count(*)统计总数问题汇总


Posted in MySQL onSeptember 23, 2022

在日常开发工作中,我经常会遇到需要统计总数的场景,比如:统计订单总数、统计用户总数等。一般我们会使用MySQL 的count函数进行统计,但是随着数据量逐渐增大,统计耗时也越来越长,最后竟然出现慢查询的情况,这究竟是什么原因呢?本篇文章带你一下学习一下。

1. MyISAM存储引擎计数为什么这么快?

我们总有个错觉,就是感觉MyISAM引擎的count计数要比InnoDB引擎更快,实际这不是错觉。

MyISAM引擎把表的总行数单独记录在磁盘上,查询的时候可以直接返回,不需要再累加统计。

但是当SQL查询中有where条件的时候,就无法再使用表的总行数了,还是需要乖乖的进行累加统计,查询性能也就跟InnoDB相差无几了。

为什么MyISAM引擎能够记录表的总行数,InnoDB引擎却不行?

因为MyISAM引擎不支持事务,只有表锁,所以记录的总行数是准确的。

而InnoDB引擎支持事务和行锁,存在并发修改的情况。又由于事务的隔离性,会出现不可重复读和幻读,记录的总行数无法保证是准确的。

2. 能不能手动实现统计总行数

既然InnoDB引擎没有帮我们记录总行数,我们能不能手动记录总行数,比如使用Redis。

其实也是不行的,使用Redis记录总行数,至少有下面3个问题:

  • 无法实现事务之间的隔离
  • 更新丢失,因为i++不是原子操作,当然可以使用Lua脚本实现原子操作,更复杂。
  • Redis是非关系型缓存数据库,不能当作关系型持久化数据库使用,一般需要设置过期时间。

MySQL count(*)统计总数问题汇总

由上图中得知,虽然Redis计数加1操作放在了事务里面,但是不受事务控制的,在事务没有提交前,其他查询依然读到了最新的总行数,这就是脏读的情况。

3. InnoDB引擎能否实现快速计数

有一种办法,可以粗略估计表的总行数,就是使用MySQL命令:

show table status like 'user';

MySQL count(*)统计总数问题汇总

真实的总行数有100万行,预估有99万多行,误差在可接受的范围内。

部分场景适用,比如粗略估计网站的总用户数。

4. 四种计数方式的性能差别

常见的统计总行数的方式有以下四种:

count(*) 、 count(常量) 、 count(id) 、 count(字段)

InnoDB引擎对count计数做了优化,会选用数据量较小的非聚簇索引进行统计。

比如用户表中有三个索引,分别是主键索引、name索引和age索引,使用执行计划查看计数的时候用到了哪个索引?

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(100) DEFAULT NULL COMMENT '姓名',
  `age` tinyint NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name` (`name`),
  KEY `idx_age` (`age`)
) ENGINE=InnoDB COMMENT='用户表';
explain select count(*) from user;

MySQL count(*)统计总数问题汇总

用到了数据量较小的age索引。

count(*) 、 count(常量) 是直接统计表中的总行数,效率较高。

而 count(id) 还需要把数据返回给MySQL Server端进行累加计数。

最后 count(字段)需要筛选不为null字段,效率最差。

四种计数的查询性能从高到低,依次是:

count(*) ≈ count(常量) > count(id) > count(字段)

对于大多数情况,得到计数结果,还是老老实实使用count(*)

所以推荐使用select count(*),别跟**select *搞混了,不推荐使用select ***的。

到此这篇关于MySQL count(*)统计总数的文章就介绍到这了,更多相关MySQL count(*)统计总数内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
详解MySQL事务的隔离级别与MVCC
Apr 22 MySQL
MySQL 8.0 之不可见列的基本操作
May 20 MySQL
MySQL官方导出工具mysqlpump的使用
May 21 MySQL
修改MySQL的数据库引擎为INNODB的方法
May 26 MySQL
MySQL中VARCHAR与CHAR格式数据的区别
May 26 MySQL
ORM模型框架操作mysql数据库的方法
Jul 25 MySQL
使用ORM新增数据在Mysql中的操作步骤
Jul 26 MySQL
面试被问select......for update会锁表还是锁行
Nov 11 MySQL
mysql分组后合并显示一个字段的多条数据方式
Jan 22 MySQL
一次SQL如何查重及去重的实战记录
Mar 13 MySQL
navicat 连接Ubuntu虚拟机的mysql的操作方法
Apr 02 MySQL
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
Jun 14 MySQL
MySQL常用慢查询分析工具详解
Aug 14 #MySQL
了解MySQL查询语句执行过程(5大组件)
Aug 14 #MySQL
MySQL 原理与优化之Update 优化
Aug 14 #MySQL
MySql统计函数COUNT的具体使用详解
Aug 14 #MySQL
MySQL 原理与优化之Limit 查询优化
MySQL 原理优化之Group By的优化技巧
Aug 14 #MySQL
mysql函数之截取字符串的实现
Aug 14 #MySQL
You might like
php配置php-fpm启动参数及配置详解
2013/11/04 PHP
php过滤html中的其他网站链接的方法(域名白名单功能)
2014/04/24 PHP
ThinkPHP结合ajax、Mysql实现的客户端通信功能代码示例
2014/06/23 PHP
写一段简单的PHP建立文件夹代码
2015/01/06 PHP
深入理解JavaScript系列(4) 立即调用的函数表达式
2012/01/15 Javascript
面向对象设计模式的核心法则
2013/11/10 Javascript
Jquery中$.post和$.ajax的用法小结
2015/04/28 Javascript
jquery实现弹出层效果实例
2015/05/19 Javascript
Javascript实现网络监测的方法
2015/07/31 Javascript
Angular JS 生成动态二维码的方法
2017/02/23 Javascript
Vue源码解析之数据响应系统的使用
2019/04/24 Javascript
在 Vue 中编写 SVG 图标组件的方法
2020/02/24 Javascript
vue引入静态js文件的方法
2020/06/20 Javascript
详解JavaScript之Array.reduce源码解读
2020/11/01 Javascript
[01:08:17]2018DOTA2亚洲邀请赛3月29日 小组赛B组 EG VS VGJ.T
2018/03/30 DOTA
Python 代码性能优化技巧分享
2012/08/07 Python
python服务器端收发请求的实现代码
2014/09/29 Python
在Python的Django框架中编写编译函数
2015/07/20 Python
发布你的Python模块详解
2016/09/15 Python
关于python的bottle框架跨域请求报错问题的处理方法
2017/03/19 Python
高效使用Python字典的清单
2018/04/04 Python
Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】
2019/01/05 Python
解决Mac下使用python的坑
2019/08/13 Python
python绘制随机网络图形示例
2019/11/21 Python
html5摇一摇代码优化包括DeviceMotionEvent等等
2014/09/01 HTML / CSS
英国护肤品购物网站:Beauty Expert
2016/08/19 全球购物
JD Sports意大利:英国篮球和运动时尚的领导者
2017/10/29 全球购物
阿姆斯特丹杜莎夫人蜡像馆官方网站:Madame Tussauds Amsterdam
2019/03/12 全球购物
网上蛋糕店创业计划书
2014/01/24 职场文书
幼儿教师工作感言
2014/02/14 职场文书
空乘英文求职信
2014/04/13 职场文书
大三学习计划书范文
2014/05/02 职场文书
运动会开幕式主持词
2015/07/01 职场文书
大学三好学生主要事迹范文
2015/11/03 职场文书
2016党员学习《反对自由主义》心得体会
2016/01/22 职场文书
分位数回归模型quantile regeression应用详解及示例教程
2021/11/02 Python