V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
qq8331199
V2EX  ›  程序员

关于大数据(千万级,亿级)的查询问题

  •  1
     
  •   qq8331199 · 2021-09-14 10:57:37 +08:00 · 4467 次点击
    这是一个创建于 1166 天前的主题,其中的信息可能已经有所发展或是发生改变。
    现在有两张表,一张工商表 6000 万数据,一张工商变更记录表 1.5 亿数据,工商表和变更记录表是一对多的关系,没有物理外键
    需要用工商 6000 万的表同步一张新的表,
    在同步的过程中需要去查变更记录表,算一些衍生数据,现在就是批量查变更记录表特别慢,
    传 1 万个“公司 id”去变更记录表都查要十几分钟,“公司 id”在变更记录表已经建了索引,但是还是慢
    已经尝试过分表,“公司 id”去 hash 分表 查询速度不是很明显
    第 1 条附言  ·  2021-09-14 17:20:38 +08:00
    传 1 万个“公司 id”去变更记录表都查要十几分钟,
    纠正一下应该是 1 万个“公司 id” 查需要 2 分钟,
    第 2 条附言  ·  2021-09-14 17:23:18 +08:00
    工商表
    company_id 主键
    name
    .....

    工商变更记录
    rec_id 主键
    company_id 普通索引
    modification
    ....
    第 3 条附言  ·  2021-09-15 13:36:19 +08:00
    感谢各位的回答,最后我决定用 MongoDB 作为中间表,先把 1.5 亿的表有需要的数据同步到 MongoDB,
    不去查 1.5 亿的表,而是查 MongoDB 的表
    第 4 条附言  ·  2021-09-23 11:26:53 +08:00
    做一个小的总结
    MongoDB 分布式解决了目前这个亿级数据的查询,MongoDB 分布式有自动分片,加上查询方面比 MySQL 快太多了不是一个数量级的,之前在 MySQL 通过 id 来查数据,1W 个 id 分批次 1000, 查 10 次( 1.5 亿数据的表) MySQL 差不多需要 2 分钟,现在换成 MongoDB 分部署并且分片,查 1W id 基本是秒级就能返回
    最后说一下,如果只是单纯的查数据没有太多关联操作,可以使用 MongoDB,速度有质的飞跃
    36 条回复    2021-09-15 15:20:06 +08:00
    ipwx
        1
    ipwx  
       2021-09-14 11:13:13 +08:00
    加内存,用内存数据结构做。

    这可能是最容易的优化方法
    wzq001
        2
    wzq001  
       2021-09-14 11:39:11 +08:00
    传 1 万个“公司 id”去变更记录表都查要十几分钟
    wzq001
        3
    wzq001  
       2021-09-14 11:40:25 +08:00
    ??? 业务需要批量变更数据?能不能单独的变更
    yidinghe
        4
    yidinghe  
       2021-09-14 11:40:51 +08:00 via Android
    试下 elastic search,将计算负担分流到多个节点
    saberlong
        5
    saberlong  
       2021-09-14 12:07:20 +08:00 via Android
    分片。把两张表拉下来,根据公司 id 分片,存到磁盘上。然后一个一个分片加载到内存中计算。磁盘持久化的 b+树上千万级,性能下降很厉害。
    ericbize
        6
    ericbize  
       2021-09-14 12:17:03 +08:00 via iPhone
    不说说什么硬件么
    zoharSoul
        7
    zoharSoul  
       2021-09-14 12:19:34 +08:00
    不说说什么硬件么
    正常来说 1w 个公司 id 去查记录表应该是秒出
    goobai
        8
    goobai  
       2021-09-14 12:51:40 +08:00 via Android
    数据同步到 es,然后再查
    qq8331199
        9
    qq8331199  
    OP
       2021-09-14 14:15:58 +08:00
    @zoharSoul @ericbize
    2t 机器硬盘+128G 内存

    @goobai @yidinghe
    试过了,es 不适合做单纯的查询,我对分词没要求,只是想查出表的数据

    @wzq001
    不是批量变更,是数据同步,需要根据查其他表,计算出衍生数据,比如新的表里面会标记出公司是否有资本增长,类似这种字段
    qq8331199
        10
    qq8331199  
    OP
       2021-09-14 14:18:17 +08:00
    @wzq001
    全量同步 6000w 数据,不可能查 6000W 次吧
    feirenK
        11
    feirenK  
       2021-09-14 14:46:35 +08:00
    hbase
    feirenK
        12
    feirenK  
       2021-09-14 14:47:12 +08:00
    ck
    ytmsdy
        13
    ytmsdy  
       2021-09-14 14:57:51 +08:00
    贴一下执行计划,这样大家可以集思广益的看一看。
    zhengsidao
        14
    zhengsidao  
       2021-09-14 15:01:54 +08:00
    用 es 去查实际上是比较快,1.5 亿的数据量很少,term query 很快就能找到。
    不过就算是用什么来存储 一万个 id 要查十几分钟,你们到底怎么存的,会这么慢
    tulumu
        15
    tulumu  
       2021-09-14 15:07:27 +08:00
    可以试试实时计算行不行
    1. 变更表 binlog 实时更新到 kv 存储中(redis/hbase)
    2. 接入主表 binlog, flink 实时 lookup 或者 lookup 缓存 来关联变更维表(redis/hbase), do something, 产生你想要的逻辑的新表
    ddkk1112
        16
    ddkk1112  
       2021-09-14 15:33:37 +08:00
    上 clickhouse
    tiiis
        17
    tiiis  
       2021-09-14 15:48:28 +08:00
    mysql ? 看看索引有没又生效哦,我们几十亿数据 mysql 分好表做好索引也可以毫秒级别的
    aragakiyuii
        18
    aragakiyuii  
       2021-09-14 16:04:42 +08:00
    数据库,表结构,索引都是什么?
    这些不知道的话挺难想思路的。。。
    ericbize
        19
    ericbize  
       2021-09-14 16:36:27 +08:00
    什么数据库? mysql 的话 看看 buff pool 是多少啊, 正常 128 G 内存 如果放 两张表 都可以全部进内存了吧
    hongweiliuruige
        20
    hongweiliuruige  
       2021-09-14 16:46:19 +08:00
    mysql8.0
    abccccabc
        21
    abccccabc  
       2021-09-14 17:00:31 +08:00
    同步一张新的表需要实时吗?不需要的话,走计划任务呗
    qq8331199
        22
    qq8331199  
    OP
       2021-09-14 17:19:09 +08:00
    @tiiis
    索引生效的
    @ericbize
    mysql 5.7
    @abccccabc
    就是离线同步太慢了 单纯的查询 1W id 放到 1.5 亿的表查询 需要 2 分钟
    @ddkk1112
    这个应用场景不太使用,我需要的是所有列的数据
    qq8331199
        23
    qq8331199  
    OP
       2021-09-14 17:19:52 +08:00
    @zhengsidao
    说错了 1W id 我测试的时候应该有人操作数据库,后面再测了一次 只用 2 分钟,但是还是慢
    abccccabc
        24
    abccccabc  
       2021-09-14 17:26:51 +08:00
    @qq8331199 有没有计算一下,处理 100 条数据需要花费多长时间?然后每隔 10 秒处理一次数据。走计划任务

    不过这数据量不算小,再怎么跑数据也要个把小时。
    qq8331199
        25
    qq8331199  
    OP
       2021-09-14 17:26:52 +08:00
    @zhengsidao
    es 也不太行,1.5 亿的数据是全部需要查的,其实我还要 3 张过亿的表需要查,之前试过全部放 es,一起查这 4 张表,速度并没有很快,还很容易超时
    qq8331199
        26
    qq8331199  
    OP
       2021-09-14 17:28:15 +08:00
    @abccccabc
    我有 6000W 数据要跑,不是 1w,1w 是我一个批次的量
    qq8331199
        27
    qq8331199  
    OP
       2021-09-14 17:31:32 +08:00
    @tiiis 我不是单独的查一个主键的记录,我这个是一次去另一张表查一批主键的记录
    tiiis
        28
    tiiis  
       2021-09-14 17:41:06 +08:00
    @qq8331199 #27 那你这还不如直接来个 join,怕影响数据库就写个 spark 程序来处理吧
    aragakiyuii
        29
    aragakiyuii  
       2021-09-14 18:54:08 +08:00 via iPhone
    1.5 亿表里就算索引生效,读的 block 也太多了
    看看这个
    https://dev.mysql.com/doc/refman/8.0/en/range-optimization.html#equality-range-optimization
    aragakiyuii
        30
    aragakiyuii  
       2021-09-14 19:01:29 +08:00 via iPhone
    再给点信息吧😂字段类型,字段索引,索引类型,还有 explain 的结果
    aragakiyuii
        31
    aragakiyuii  
       2021-09-14 19:03:16 +08:00 via iPhone
    或者不如找个内存大的服务器读到内存里去处理
    ericbize
        32
    ericbize  
       2021-09-14 20:29:40 +08:00 via iPhone
    @qq8331199 先看看是不是 table per file, 如果是的话 你可以试试整理一下? (可能有卡死的风险)你看看是不是 innodb, 不过建议先让 dba 能不能处理一下先
    aru
        33
    aru  
       2021-09-14 20:47:30 +08:00
    上 greenplum 吧,只要你的硬盘性能跟得上,上尽量多的 segment,非常快
    qq8331199
        34
    qq8331199  
    OP
       2021-09-15 10:08:42 +08:00
    @aragakiyuii
    company_id 普通索引 varchar 类型,上面已经说了,explain 显示是走索引的,
    你有试过 1.5 亿里面查 1W 数据要多久吗?不是走主键索引,走普通索引
    qq8331199
        35
    qq8331199  
    OP
       2021-09-15 10:11:34 +08:00
    @tulumu
    我要的是查另一张表的数据,和主表没上面关系,瓶颈在全量同步,因为全量同步的时候查 1.5 亿的表慢,现在想解决的是查询慢的问题
    MonkeyJon
        36
    MonkeyJon  
       2021-09-15 15:20:06 +08:00
    @qq8331199
    1.分批次同步,一次几千,尝试出最高效率的同步数,也就是 1.5 亿那张表的查询最快的数量
    2.多线程,分页,
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1178 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 23:59 · PVG 07:59 · LAX 15:59 · JFK 18:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.