CodeXx
V2EX  ›  数据库

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

  •  
  •   CodeXx · Sep 29, 2020 · 7489 views
    This topic created in 2230 days ago, the information mentioned may be changed or developed.

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

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

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

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

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

    这样也许行
    RickyC
    RickyC
    Sep 29, 2020
    7
    接上
    如果你每天还有 10w 的数据更改, 可以在每次更改的时候修改 count 表.

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


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


    2.来吧业务查询中间件,把 query 拆分为若干 subquery,再分发到不同实例,最后汇总,但是到这一步已经快超出 rds 范畴了,查询速度还不能接受的话考虑其他方式
    G2bN4dbX9J3ncp0r
    G2bN4dbX9J3ncp0r
    Sep 29, 2020
    45
    @CodeXx 分页查询用 我之前都是去掉 count😄
    xuewuchen
    xuewuchen
    Sep 30, 2020
    46
    索引吧。。。LAST ID
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   821 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 91ms · UTC 23:36 · PVG 07:36 · LAX 15:36 · JFK 18:36
    ♥ Do have faith in what you're doing.