大家都在用MySQL count(*)统计总数,到底有什么问题?
在日常开发工作中,我经常会遇到需要统计总数的场景,比如:统计订单总数、统计用户总数等。一般我们会使用MySQL 的count函数进行统计,但是随着数据量逐渐增大,统计耗时也越来越长,最后竟然出现慢查询的情况,这究竟是什么原因呢?本篇文章带你一下学习一下。
1. MyISAM存储引擎计数为什么这么快?
我们总有个错觉,就是感觉MyISAM引擎的count计数要比InnoDB引擎更快,实际这不是错觉。
MyISAM引擎把表的总行数单独记录在磁盘上,查询的时候可以直接返回,不需要再累加统计。
但是当SQL查询中有where条件的时候,就无法再使用表的总行数了,还是需要乖乖的进行累加统计,查询性能也就跟InnoDB相差无几了。
为什么MyISAM引擎能够记录表的总行数,InnoDB引擎却不行?
因为MyISAM引擎不支持事务,只有表锁,所以记录的总行数是准确的。
而InnoDB引擎支持事务和行锁,存在并发修改的情况。又由于事务的隔离性,会出现不可重复读和幻读,记录的总行数无法保证是准确的。
2. 能不能手动实现统计总行数
既然InnoDB引擎没有帮我们记录总行数,我们能不能手动记录总行数,比如使用Redis。
其实也是不行的,使用Redis记录总行数,至少有下面3个问题:
- 无法实现事务之间的隔离
- 更新丢失,因为i++不是原子操作,当然可以使用Lua脚本实现原子操作,更复杂。
- Redis是非关系型缓存数据库,不能当作关系型持久化数据库使用,一般需要设置过期时间。

由上图中得知,虽然Redis计数加1操作放在了事务里面,但是不受事务控制的,在事务没有提交前,其他查询依然读到了最新的总行数,这就是脏读的情况。
3. InnoDB引擎能否实现快速计数
有一种办法,可以粗略估计表的总行数,就是使用MySQL命令:
show table status like 'user';

真实的总行数有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;

用到了数据量较小的age索引。
count(*) 、 count(常量) 是直接统计表中的总行数,效率较高。
而 count(id) 还需要把数据返回给MySQL Server端进行累加计数。
最后 count(字段)需要筛选不为null字段,效率最差。
四种计数的查询性能从高到低,依次是:
count(*) ≈ count(常量) > count(id) > count(字段)
对于大多数情况,得到计数结果,还是老老实实使用count(*)
所以推荐使用select count(*),别跟**select *搞混了,不推荐使用select ***的。

大家都在用MySQL count(*)统计总数,到底有什么问题?的更多相关文章
- MySQL的统计总数count(*)与count(id)或count(字段)的之间的各自效率性能对比
执行效果: 1. count(1) and count(*) 当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count(*)用时多了! 从执行计划来看,count(1)和cou ...
- MySQL统计总数就用count(*),别花里胡哨的《死磕MySQL系列 十》
有一个问题是这样的统计数据总数用count(*).count(主键ID).count(字段).count(1)那个效率高. 先说结论,不用那么花里胡哨遇到统计总数全部使用count(*). 但是有很多 ...
- 【mysql】 mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件 【mybatis】count 统计+JSON查询
mybatis实现 主从表 left join 1:n 一对多 分页查询 主表从表都有查询条件+count 需求: ======================================= ...
- MySql的count统计结果
起因:最近在学习mysql的数据库,发现在innodb表中大数据量下count(*)的统计结果实在是太慢,所以想找个办法替代这种查询,下面分享一下我查找的过程. 实践:在给出具体的结论之前,我们先看看 ...
- sql中奇怪的sum(1),sum(2),count(1),count(6),count(*):统计总数
sql的统计函数 sql统计函数有 count 统计条数,配合group用 sum 累加指定字段数值 但注意sum(1)就特殊 sum(1)等同于count(*) sum(1)统计个数,功能和coun ...
- mysql count group by统计条数方法
mysql count group by统计条数方法 mysql 分组之后如何统计记录条数? gourp by 之后的 count,把group by查询结果当成一个表再count一次select c ...
- MySQL查询统计,统计唯一值并分组
做个笔记 SQLyog客户端访问MySQL服务器 统计数据:次数总数, 次数成功率,对象(obj)总数,对象(obj)成功率 要求:按时间排序和分组 sql语句如下: SELECT a.date AS ...
- mysql数据统计技巧备忘录
mysql 作为常用数据库,操作贼六是必须的,对于数字操作相关的东西,那是相当方便,本节就来拎几个统计案例出来供参考! order订单表,样例如下: CREATE TABLE `t_order` ( ...
- Mysql count+if 函数结合使用
Mysql count+if 函数结合使用 果林椰子 关注 2017.05.18 13:48* 字数 508 阅读 148评论 0喜欢 1 涉及函数 count函数 mysql中count函数用于统计 ...
随机推荐
- CesiumJS 2022^ 源码解读[0] - 文章目录与源码工程结构
很高兴你能在浮躁的年代里还有兴趣阅读源代码,CesiumJS 至今已有十年以上,代码量也积累了三十多万行(未压缩状态). 我也很荣幸自己的文章能被读者看到,如果对你有帮助.有启发,点个赞就是对我最大的 ...
- Windows JDK 的下载与安装
Java Development Kit 简称 JDK,任何需要开发 Java 程序的环境都需要进行安装 JDK. JDK 下载地址:https://www.oracle.com/java/techn ...
- springboot和mybatis 配置多数据源
主数据源(由于代码没有办法复制的原因,下面图片和文字不一致) package com.zhianchen.mysqlremark.toword.config;import com.zaxxer.hik ...
- DENIED Redis is running in protected mode because protected mode is enabled
DENIED Redis is running in protected mode because protected mode is enabled redisson连接错误 Unable to i ...
- 自己写雪花算法IdWorker
package com.aiyusheng.shopping.util; import java.lang.management.ManagementFactory; import java.net. ...
- atcoder ABC 232 B~E题解
B 模拟,水题 #include<bits/stdc++.h> using namespace std; char s1[100005],s2[100005]; int a1[100005 ...
- ElementUI嵌套页面及关联增删查改实现
@ 目录 前言 一.ElementUI如何在原有页面添加另外一个页面并实现关联增删查改? 二.实现步骤 1.ElementUI代码 2.思路:很简单 1.1 首先通过el-row.el-col.el- ...
- Dubbo源码(三) - 服务导出(生产者)
前言 本文基于Dubbo2.6.x版本,中文注释版源码已上传github:xiaoguyu/dubbo 在了解了Dubbo SPI后,我们来了解下Dubbo服务导出的过程. Dubbo的配置是通过Du ...
- 从零开始在centos搭建博客(一)
本篇为安装篇. 基于centos 7.9,大部分东西使用docker安装. 软件列表:docker + mysql + wordpress 安装docker yum install -y yum-ut ...
- Yii ACF(accessController)简单控权
use yii\filters\AccessControl; class SiteController extends Controller { public function behaviors() ...