关于 mysql count 太慢的问题

2022-10-06 18:51:35 +08:00
 chenqh

200W 的数据量,count(*)就要 3S 多了

有什么办法提升没有?

使用 cache?但是 count(*)的时候 where 并不是固定的

求指点

4472 次点击
所在节点    MySQL
36 条回复
cp19890714
2022-10-06 23:35:37 +08:00
首先需求是否合理?百万数据,精确 count 意义是什么?
我从来没有找到有哪种场景真的有这个需求。

如果是为了分页, 那么可以做个假 total ,只要 currentPageSize 大于或等于 pageSize ,就认为可能有下一页,returnTotal = pageNo * pageSize + 1. 用户就可以一直点下一页,直到最后一页。

如果是为了看大概的数据量,那么可以定时任务跑,根据条件(例如时间段)分多次查询,最后相加,放缓存。

用户需要知道精确 count 时,数据量一定是小的。
数据量大的时候,用户一定不需要知道精确 count 。
mythabc
2022-10-06 23:37:55 +08:00
用 flink 做实时 count ,结果实时写入 kafka
zoharSoul
2022-10-07 01:26:16 +08:00
@lmshl #3 索引概率分布估算一个值
大佬可以讲下 mysql 怎么估算这个值吗?
dobelee
2022-10-07 02:09:12 +08:00
无解的。可以做个简单的 cache ,一般很少人翻到最后一页,很多产品最后几页都不准,比如豆瓣。
minsheng
2022-10-07 03:47:08 +08:00
@lmshl 也不是完全不行,我之前看 CouchDB 的设计,它们的核心亮点就是可以对每个文档(这是个 NoSQL 的文档数据库)做持久化的 flat map + reduce ,就类似建立 index 一样把 map reduce 的结果存在硬盘上。用的是 B+树,把每个树的子节点的 reduce 结果都会存在 B+树的分支节点上,这样可以快速的(指数级复杂度)对连续区间的数据进行 reduce ,这就包括了题主的问题。
minsheng
2022-10-07 03:57:59 +08:00
我又想了一下,如果不需要 filter 的话,即每次只支持查询时间 a 到 b 之间的全部数据,数据的时间戳是单调递增的话,或许也不是不能用我说的这个树这样的想法?

手机打字,我就边打边算了。假设两个月生成两百万数据,那么一天在三万左右,每分钟 24 个。那可不可以每分钟跑个程序,统计一下那个分钟有多少数据,然后每三十分钟请求一下,刚刚三十分钟分钟有多少数据。注意你这个时候就可以直接加过去三十分钟已经算好的三十行了。然后依次类推,九百分钟一个单元,两万七千分钟一个单元(十八点七五天),这样这颗树不会很高。

查询的时候,你就把时间切成这样的区间,比如说查询 3min 到 180min ,你就把 30 、60 、90 、120 、150 这五行取出来加一下,再把 3 到 29 这二十多行加一下,最后累加就好了。
xuanbg
2022-10-07 16:28:58 +08:00
其实不精确的 count 也很难的。。。难就难在某个条件可能 count 很小,换个条件就很大。譬如订单状态,你查已完成订单,数量就大得不得了;待付款的总是很少。。。如果你查的是已完成,那查起来很慢,但没有出结果前你不能确定他慢啊。等你知道慢,结果也出来了,还优化个毛线啊。
jhdxr
2022-10-07 17:45:11 +08:00
虽然我也完全赞同大数据情况下还得精确统计这种需求的合理性在哪的问题,
但 200W 的 count 要 3s+,我觉得可以看看用的是 SSD 还是机械硬盘,还有就是索引的利用情况。
route
2022-10-07 18:00:16 +08:00
要是是有限的几条语句,就每隔时间间隔去执行语句,再存到缓存中,下次用直接拿出来就好了
nicoljiang
2022-10-08 08:43:20 +08:00
@chenqh 我 pg count 1000 万数据只需要 500ms ,没有什么索引。跟 pg 比起来,MySQL 都不算合格的数据库。
chenqh
2022-10-08 09:12:44 +08:00
chenqh
2022-10-08 09:16:55 +08:00
@jhdxr 我虚拟机测的,200W COUNT 是没加条件的,我虚拟机是装在 SSD 上面的,但是问题是可能会加条件,这个页面就是管理后后的一个列表页面,上面一堆输入堆,下面一个 table
Maxwe11
2022-10-08 18:33:01 +08:00
mysql 本身也不适合干这个活儿;

如果你是生产库,那更不适合干这个,没事儿总 count 容易挂;

看你的延迟需求,是不是说一定要实时 count ,还是准实时,对于这类聚合,如果不是要求绝对实时,踏踏实实另搭个 clickhouse ,你再加个 0 也是秒出
nicoljiang
2022-10-08 21:23:55 +08:00
@chenqh pg 的 很多函数比 MySQL 快非常多,MySQL 都是残血版。
chenqh
2022-10-08 21:30:51 +08:00
@nicoljiang 可惜我 pg 不会,现在也懒得去学了 pg 了,又不是自己当老板,学 PG 有什么用,老板叫用什么用什么咯
ShuA1
2022-10-08 22:04:38 +08:00
explain

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/884917

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX