MySQL 单表三千万条数据,怎么优化 count 查询? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
CodeXx
V2EX    数据库

MySQL 单表三千万条数据,怎么优化 count 查询?

  •  
  •   CodeXx 2020-09-29 10:38:41 +08:00 6629 次点击
    这是一个创建于 1906 天前的主题,其中的信息可能已经有所发展或是发生改变。

    innodb,20 来个字段,每天有几十万条数据插入,在不做分表的情况下,怎么优化查询?现在是 count 查询很慢,5s 左右,带上查询条件比如近一个月就更慢了 10 多 s

    46 条回复    2020-09-30 10:47:06 +08:00
    Joyboo
        1
    Joyboo  
       2020-09-29 10:54:31 +08:00
    分区,索引
    G2bN4dbX9J3ncp0r
        2
    G2bN4dbX9J3ncp0r  
       2020-09-29 10:55:29 +08:00
    可以不做 count,就不做
    非做的话,看看能不能自己统计

    或者放 es 里?
    CodeXx
        3
    CodeXx  
    OP
       2020-09-29 11:05:15 +08:00
    @Joyboo 索引对 count 查询貌似没用,还是得扫描全表
    CodeXx
        4
    CodeXx  
    OP
       2020-09-29 11:05:47 +08:00
    @lidashuang 分页查询用到的,也不知道会用什么条件查询
    huntcool001
        5
    huntcool001  
       2020-09-29 11:13:03 +08:00   2
    每天晚上把到零点的数据库的数据,离线做分析统计,count+各种查询条件等等(大概 es 或者其他框架,我不是很清楚), 结果存起来.

    然后每天的数据,你有了当天零点以来的 binlog,就有了增量的 count. 和离线分析做出来的 count 结合起来.

    大概是这个思路. 大厂都是这么干的.
    RickyC
        6
    RickyC  
       2020-09-29 11:17:10 +08:00
    如果数据库不经常改变
    根据查询条件建立几个 count 表, 里面保存根据各种条件得到的 count 数字;
    并给 count 表建立索引

    这样也许行
    RickyC
        7
    RickyC  
       2020-09-29 11:19:34 +08:00
    接上
    如果你每天还有 10w 的数据更改, 可以在每次更改的时候修改 count 表.

    我觉得用 count 表可能解决你的问题.预先统计
    egglin
        8
    egglin  
       2020-09-29 11:24:42 +08:00
    异构吧,es + mysql
    maigebaoer
        9
    maigebaoer  
       2020-09-29 11:31:40 +08:00 via Android
    如果直接 count,用 count(*)吧,没啥特别好的建议。要不就直接入库前统计,写 count 字段。
    mrhhsg
        10
    mrhhsg  
       2020-09-29 11:33:21 +08:00
    三千万的 count 那还不是一瞬间的事?加内存就完了
    v2orz
        11
    v2orz  
       2020-09-29 11:35:28 +08:00
    插入的时候维护 count 信息?同 9L
    Leigg
        12
    Leigg  
       2020-09-29 11:44:35 +08:00 via Android   1
    不要做实时查询即可,延迟个 30s 几分钟,数量到达一定高度后,多数场景中的实时统计就变成了一种伪需求,如果一定需要,换数据库,比如 clickhouse
    RangerWolf
        13
    RangerWolf  
       2020-09-29 11:46:37 +08:00
    12 楼+1,clickhouse 的统计非常
    dongisking
        14
    dongisking  
       2020-09-29 11:47:39 +08:00
    这问题我这边也遇到过,特别是做管理后台特别多复杂的条件做 where 的 count 根本无法缓存,最后的解决办法是把 count 缓存,然后页面显示“大约 xx 条”,每一段时间更新一次
    cccy0
        15
    cccy0  
       2020-09-29 11:55:01 +08:00
    近实时统计的话建议放 es
    sagaxu
        16
    sagaxu  
       2020-09-29 12:00:25 +08:00 via Android
    @CodeXx 索引 count 时有没有用,要看区分度,你索引类似性别这种低区分度的当然没用
    liuzhaowei55
        17
    liuzhaowei55  
       2020-09-29 12:05:13 +08:00 via Android
    不要使用 count,如果是 id 自增而且没有删除数据可以使用最后一条数据的 id,或者使用 explain 返回的 rows,这个值不太准但响应很快
    nomansky
        18
    nomansky  
       2020-09-29 12:29:18 +08:00
    加个表,里面保存 count,每插入一条数据更新 count
    haohappy
        19
    haohappy  
       2020-09-29 12:55:12 +08:00
    count 慢 select 不慢吗
    dzdh
        20
    dzdh  
       2020-09-29 12:58:18 +08:00
    @CodeXx 分页场景的话,where 排序字段 >上一页的最大值 limt x, n
    juntao
        21
    juntao  
       2020-09-29 13:10:53 +08:00
    最近有遇到,多字段 WHERE 查询,1kw 条不到,不想分表
    1 做好索引。可以用 EXPLAIN 来帮助优化。 -- 有一定效果
    2 限制查询的时间范围 -- 特别有效
    3 异构,mysql,redis 、elasticsearch 等等单独统计数据, 因为 2 能够满足我们的需求,所以没采用。


    @liuzhaowei55 直接获取自增 id 也是一种方法诶。之前没考虑,需要匹配场景。
    fuyufjh
        22
    fuyufjh  
       2020-09-29 13:12:19 +08:00
    mysql 8.0 有 parallel query,能大幅提升这个场景
    zakokun
        23
    zakokun  
       2020-09-29 13:13:58 +08:00
    1. 索引对 count 有用
    2. 几千万的表 count 需求来自哪里?为何要每天 count
    3. 维护一个 count 表,插入数据的时候更新 count 表
    4. ES
    hooopo
        24
    hooopo  
       2020-09-29 13:17:26 +08:00 via Android
    j747677392
        25
    j747677392  
       2020-09-29 13:51:42 +08:00
    如果都是日志型的数据(用于分析,没删改的话) 可以用 hdfs+imapla,支持 sql,几亿数据查询毫秒吧
    wangyzj
        26
    wangyzj  
       2020-09-29 14:02:04 +08:00
    count 和索引没关系
    es 是个选项
    或者单独做个统计信息表
    或者用 redis 来分页
    CodeXx
        27
    CodeXx  
    OP
       2020-09-29 14:18:20 +08:00
    @RickyC
    @maigebaoer
    @v2orz
    @Leigg
    @RangerWolf
    这样只能存总的 count 吧,查询有其他条件的更慢,14 楼这种差不多
    CodeXx
        28
    CodeXx  
    OP
       2020-09-29 14:19:31 +08:00
    @haohappy select 很快
    cokolin
        29
    cokolin  
       2020-09-29 14:29:22 +08:00
    能否首先描述一下为何要 count,例如页面查询需要总量,还是什么需要
    cokolin
        30
    cokolin  
       2020-09-29 14:33:45 +08:00
    还有查询用到的字段是否是固定的,如果的固定的话,是否可以增加索引,看看 EXPLAIN 分析用到的索引是否正确
    另外也可以用一些业务的方式避免分页查询总量的
    xsm1890
        31
    xsm1890  
       2020-09-29 14:42:26 +08:00
    myisam 自动维护总数,count 的过程不用计算只需要度数即可
    raysmond
        32
    raysmond  
       2020-09-29 14:45:16 +08:00
    如果只是 count,且对实时性要求那么高(能接受 10s ?),有个很简单的做法能大幅提高速度
    用一个线程异步 count 就好,用的地方直接从内存取,对使用方来说超级快
    fangcan
        33
    fangcan  
       2020-09-29 14:49:17 +08:00
    不要求精确的话 用 explain
    Evilk
        34
    Evilk  
       2020-09-29 15:20:39 +08:00
    如果是分页用的 count,如果数据量太大,我一般给个模糊值
    每隔段时间,更新一次,即可
    liwl
        35
    liwl  
       2020-09-29 15:21:35 +08:00
    是想弄图表吧 每天 count
    rickiey
        36
    rickiey  
       2020-09-29 16:27:40 +08:00
    mongoDB shared cluster 不行吗? 我没用过
    lshero
        37
    lshero  
       2020-09-29 16:29:48 +08:00
    OLAP 的功能交给别的数据库做吧
    mofeishiwo
        38
    mofeishiwo  
       2020-09-29 16:32:34 +08:00
    megatron7
        39
    megatron7  
       2020-09-29 17:06:00 +08:00
    没有数据断层吧并且有自增主键索引可以用:
    select max(id) from table;
    bbao
        40
    bbao  
       2020-09-29 17:07:23 +08:00
    @CodeXx mysql 是行锁,是否全表需要看你后面 where 条件。
    ragnaroks
        41
    ragnaroks  
       2020-09-29 17:10:07 +08:00
    做个同步的从库,统计类需求从从库查,不影响主库业务
    vus520
        42
    vus520  
       2020-09-29 17:11:57 +08:00
    1,能不 count 就不 count
    2,Mysql 有触发器,能不能插入的时候写到其它某个 value 上
    3,缓存神器你值得拥有
    liyunlong41
        43
    liyunlong41  
       2020-09-29 17:18:03 +08:00 via iPhone
    加索引应该也要扫描索引树吧。
    插入的时候更新 count,似乎会影响插入效率。
    将数据同步到其他数据库例如 es 或者从库,查询从这些里面查好像不错。
    定时任务周期性的计算 count 也可以,查询时直接用结果,也是有一定的时延。
    everhythm
        44
    everhythm  
       2020-09-29 18:25:34 +08:00 via iPhone
    1.索引 or 各种缩小量级的方法对 count 有效,所以最近一个月的 count 你可以优化


    2.来吧业务查询中间件,把 query 拆分为若干 subquery,再分发到不同实例,最后汇总,但是到这一步已经快超出 rds 范畴了,查询速度还不能接受的话考虑其他方式
    G2bN4dbX9J3ncp0r
        45
    G2bN4dbX9J3ncp0r  
       2020-09-29 20:59:42 +08:00
    @CodeXx 分页查询用 我之前都是去掉 count
    xuewuchen
        46
    xuewuchen  
       2020-09-30 10:47:06 +08:00
    索引吧。。。LAST ID
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1336 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 35ms UTC 17:02 PVG 01:02 LAX 09:02 JFK 12:02
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86