› 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
rqxiao
V2EX  ›  MySQL

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

  •  
  •   rqxiao · Aug 26, 2022 · 6374 views
    This topic created in 1531 days ago, the information mentioned may be changed or developed.
    单表 5 千万 现在 count(*) 要 17s 左右
    36 replies  •  2022-09-09 15:24:48 +08:00
    C02TobNClov1Dz56
    C02TobNClov1Dz56
    Aug 26, 2022
    1
    看你带条件了没, 条件是否走上索引了.
    MoYi123
    MoYi123
    Aug 26, 2022
    2
    据我所知 pg 是没有的, mysql 应该也没有.
    KouShuiYu
    KouShuiYu
    Aug 26, 2022
    3
    换成 count(1) 然后加上索引
    pannanxu
    pannanxu
    Aug 26, 2022
    4
    据说这样子可以

    explain select id from project

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

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

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

    不过我感觉你可能表设计有问题或者硬盘 IO 被拖爆了? 再怎么慢,5000 万数据 17S 也有点离谱啊.......
    bootvue
    bootvue
    Aug 26, 2022
    10
    这个数据量是时候考虑考虑 es clickhouse 这些了
    rqxiao
    rqxiao
    OP
    Aug 26, 2022
    11
    有 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
    zibber
    Aug 26, 2022
    12
    clickhouse
    MoYi123
    MoYi123
    Aug 26, 2022
    13
    建议直接说服产品, 分页改成一页页翻, 用上一页的主键去查下一页, 然后行数大于 10000 行直接显示 10000+. 基本只能这么做.
    keenkiller
    keenkiller
    Aug 26, 2022
    14
    改成下拉分页,别算总数了。
    dwlovelife
    dwlovelife
    Aug 26, 2022
    15
    用 mysql 一句话 无解, 要么改需求, 要么上别的数据库
    CEBBCAT
    CEBBCAT
    Aug 26, 2022
    16
    @KouShuiYu #3 真佩服,能一下子猜到楼主是附带了 WHERE 的计数👍
    makelove
    makelove
    Aug 26, 2022
    17
    先想明白你要的是什么,而不是怎么实现
    5 千万级保证实现精确,这 tm 什么需求,造火箭都不需要这么高精度
    djoiwhud
    djoiwhud
    Aug 26, 2022 via Android
    18
    条件未命中索引,或者是结果集超比例,触发了全表扫描。

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

    做数据冗余,规避汇总语句,也是可以的。
    djoiwhud
    djoiwhud
    Aug 26, 2022 via Android
    19
    不带条件的 sql ,别说五千万,就是一个亿,count *也可以快速查询出来。
    这个问题换 count 1 没任何影响。
    honamx
    honamx
    Aug 26, 2022
    20
    建组合索引试试,is_deleted, data_type, fileType, fileSource ,auditStatus
    Red998
    Red998
    Aug 26, 2022
    21
    mysql 数据达到瓶颈了 、再怎么优化还是性能差的。考虑做数据切分 分表之类的。
    chendl111
    chendl111
    Aug 26, 2022 via Android
    22
    换 lykasm
    bthulu
    bthulu
    Aug 26, 2022
    23
    触发器啊, 新增一条满足查询条件的数据就记录+1, 删除一条就记-1. 后面只查这个记录数就行了, 1 毫秒都用不到就能精确返回
    justanetizen
    justanetizen
    Aug 26, 2022
    24
    加个表或者缓存里存储该表的总数据数
    pengtdyd
    pengtdyd
    Aug 26, 2022
    25
    这不是技术的问题,这是产品的问题。
    justanetizen
    justanetizen
    Aug 26, 2022
    26
    还有一个办法,用 insert 、delete 触发器
    yousabuk
    yousabuk
    Aug 26, 2022 via iPhone
    27
    换 myisam
    taogen
    taogen
    Aug 26, 2022
    29
    表结构、索引和 explain 贴一下啊
    akira
    akira
    Aug 26, 2022
    30
    产品问题,改成查最近一段时间的 数据,例如 30 天,7 天, 然后这样就可以走索引了。
    hubahuba
    hubahuba
    Aug 27, 2022
    31
    这这这不分表
    iseki
    iseki
    Aug 27, 2022 via Android
    32
    才 5000 万分啥表
    KouShuiYu
    KouShuiYu
    Aug 28, 2022
    33
    检查下 where 条件是不是有类型转换之类的操作,之前有张表
    conv_time :: date between :dateStart and :dateEnd
    修改成了 conv_time between :dateStart and (date :dateEnd + interval '1 day' - interval '1 second')
    查询时间直接从 3s 干到了 20ms
    CrazyMonkeyV
    CrazyMonkeyV
    Aug 29, 2022
    34
    我们也遇到了这个问题,在特定需求下,近乎无解。
    NoahVI
    NoahVI
    Sep 9, 2022
    35
    @qq8331199 那还是用 binlog 好点。
    NoahVI
    NoahVI
    Sep 9, 2022
    36
    还是考虑用 es 吧
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2905 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 78ms · UTC 12:39 · PVG 20:39 · LAX 04:39 · JFK 07:39
    ♥ Do have faith in what you're doing.