rqxiao
V2EX  ›  MySQL

mysql 单表 5 千万的数据量 , count(*) 耗时很长有办法优化吗

By rqxiao at 2022 年 8 月 26 日 · 6221 次点击
单表 5 千万 现在 count(*) 要 17s 左右
36 条回复  •  2022-09-09 15:24:48 +08:00
C02TobNClov1Dz56
   1
C02TobNClov1Dz56  
   2022 年 8 月 26 日
看你带条件了没, 条件是否走上索引了.
MoYi123
   2
MoYi123  
   2022 年 8 月 26 日
据我所知 pg 是没有的, mysql 应该也没有.
KouShuiYu
   3
KouShuiYu  
   2022 年 8 月 26 日
换成 count(1) 然后加上索引
pannanxu
   4
pannanxu  
   2022 年 8 月 26 日
据说这样子可以

explain select id from project

或者如果数据量准确度不需要太高,可以直接把查出来的数量丢进缓存
Greg7788
   5
Greg7788  
   2022 年 8 月 26 日
直接是没有办法的,就是慢
要么 redis 缓存这个 count ,先 count 一次,后面有增删,就去更新这个 count
keepeye
   6
keepeye  
   2022 年 8 月 26 日
正在显示第 0 - 24 行 (共 31392729 行, 查询花费 13.9842 秒。)
SELECT count(*) FROM `orders`

rds 8 核 16g 高可用实例
sivacohan
   7
sivacohan  
   2022 年 8 月 26 日
select TABLE_ROWS from information_schema.TABLES where TABLE_SCHEMA = 'db' AND TABLE_NAME='tbl';

不要求准确性的话,可以这么查询。
keepeye
   8
keepeye  
   2022 年 8 月 26 日
不求精确的话,并且能查询 mysql 库的话,可以读取 innodb_table_stats
westoy
   9
westoy  
   2022 年 8 月 26 日
缓存啊

不过我感觉你可能表设计有问题或者硬盘 IO 被拖爆了? 再怎么慢,5000 万数据 17S 也有点离谱啊.......
bootvue
   10
bootvue  
   2022 年 8 月 26 日
这个数据量是时候考虑考虑 es clickhouse 这些了
rqxiao
   11
rqxiao  
OP
   2022 年 8 月 26 日
有 where 条件的,而且还比较多

SELECT COUNT(1) FROM tb_task
<where>
AND is_deleted = 0
AND data_type != 1
<if test="fileType != null and fileType != ''"> AND file_type = #{fileType}</if>
<if test="fileSource != null"> AND file_source = #{fileSource}</if>
<if test="auditStatus != null"> AND review_status = #{auditStatus}</if>
<if test="auditStatus != null"> AND analysis_status = 2</if>
zibber
   12
zibber  
   2022 年 8 月 26 日
clickhouse
MoYi123
   13
MoYi123  
   2022 年 8 月 26 日
建议直接说服产品, 分页改成一页页翻, 用上一页的主键去查下一页, 然后行数大于 10000 行直接显示 10000+. 基本只能这么做.
keenkiller
   14
keenkiller  
   2022 年 8 月 26 日
改成下拉分页,别算总数了。
dwlovelife
   15
dwlovelife  
   2022 年 8 月 26 日
用 mysql 一句话 无解, 要么改需求, 要么上别的数据库
CEBBCAT
   16
CEBBCAT  
   2022 年 8 月 26 日
@KouShuiYu #3 真佩服,能一下子猜到楼主是附带了 WHERE 的计数👍
makelove
   17
makelove  
   2022 年 8 月 26 日
先想明白你要的是什么,而不是怎么实现
5 千万级保证实现精确,这 tm 什么需求,造火箭都不需要这么高精度
djoiwhud
   18
djoiwhud  
   2022 年 8 月 26 日 via Android
条件未命中索引,或者是结果集超比例,触发了全表扫描。

优化办法,优化 sql ,优化索引。如果是结果集超大,导致索引查询转全表扫描,需要考虑需求调整。或者是技术方案调整。

做数据冗余,规避汇总语句,也是可以的。
djoiwhud
   19
djoiwhud  
   2022 年 8 月 26 日 via Android
不带条件的 sql ,别说五千万,就是一个亿,count *也可以快速查询出来。
这个问题换 count 1 没任何影响。
honamx
   20
honamx  
   2022 年 8 月 26 日
建组合索引试试,is_deleted, data_type, fileType, fileSource ,auditStatus
Red998
   21
Red998  
   2022 年 8 月 26 日
mysql 数据达到瓶颈了 、再怎么优化还是性能差的。考虑做数据切分 分表之类的。
chendl111
   22
chendl111  
   2022 年 8 月 26 日 via Android
换 lykasm
bthulu
   23
bthulu  
   2022 年 8 月 26 日
触发器啊, 新增一条满足查询条件的数据就记录+1, 删除一条就记-1. 后面只查这个记录数就行了, 1 毫秒都用不到就能精确返回
justanetizen
   24
justanetizen  
   2022 年 8 月 26 日
加个表或者缓存里存储该表的总数据数
pengtdyd
   25
pengtdyd  
   2022 年 8 月 26 日
这不是技术的问题,这是产品的问题。
justanetizen
   26
justanetizen  
   2022 年 8 月 26 日
还有一个办法,用 insert 、delete 触发器
yousabuk
   27
yousabuk  
   2022 年 8 月 26 日 via iPhone
换 myisam
taogen
   29
taogen  
   2022 年 8 月 26 日
表结构、索引和 explain 贴一下啊
akira
   30
akira  
   2022 年 8 月 26 日
产品问题,改成查最近一段时间的 数据,例如 30 天,7 天, 然后这样就可以走索引了。
hubahuba
   31
hubahuba  
   2022 年 8 月 27 日
这这这不分表
iseki
   32
iseki  
   2022 年 8 月 27 日 via Android
才 5000 万分啥表
KouShuiYu
   33
KouShuiYu  
   2022 年 8 月 28 日
检查下 where 条件是不是有类型转换之类的操作,之前有张表
conv_time :: date between :dateStart and :dateEnd
修改成了 conv_time between :dateStart and (date :dateEnd + interval '1 day' - interval '1 second')
查询时间直接从 3s 干到了 20ms
CrazyMonkeyV
   34
CrazyMonkeyV  
   2022 年 8 月 29 日
我们也遇到了这个问题,在特定需求下,近乎无解。
NoahVI
   35
NoahVI  
   2022 年 9 月 9 日
@qq8331199 那还是用 binlog 好点。
NoahVI
   36
NoahVI  
   2022 年 9 月 9 日
还是考虑用 es 吧
› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
© 2026 V2EX · 89ms · 3.9.8.5