V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐工具
RoboMongo
推荐书目
50 Tips and Tricks for MongoDB Developers
Related Blogs
Snail in a Turtleneck
dtgxx
V2EX  ›  MongoDB

mongodb 导入数据怎么破

  •  
  •   dtgxx · Jul 29, 2020 · 7278 views
    This topic created in 2106 days ago, the information mentioned may be changed or developed.

    数据量太大 几百亿,但是只有一台机器,存储够用。


    数据需要以三个字段建联合唯一索引。


    如果不建索引,导入差不多一周就完事了。 但是联合唯一索引在导入数据之后有重复数据就无法创建了,去掉重复数据也非常的难。 建索引之后再导数据,非常非常非常的慢,可能是索引影响了插入速度。。


    大佬们有啥高招吗

    34 replies    2020-08-08 15:16:43 +08:00
    wupher
        1
    wupher  
       Jul 29, 2020
    那就不要用唯一性索引
    dtgxx
        2
    dtgxx  
    OP
       Jul 29, 2020
    @wupher #1 尴尬。。。这个是刚需。。
    abcbuzhiming
        3
    abcbuzhiming  
       Jul 29, 2020
    不能自己写程序读取数据,然后在去重的基础上导入吗?无非就是慢一点呗
    dtgxx
        4
    dtgxx  
    OP
       Jul 29, 2020
    @abcbuzhiming #3 写了很多程序,也做了非常多的优化,慢的不行。。数据量太大,程序无法支持去重的。
    jiangzhuo
        5
    jiangzhuo  
       Jul 29, 2020   ❤️ 1
    去阿里云 AWS 之类的开一套高性能的机器,导入,然后关闭数据库,把导入好的文件传回你那台机器,用导好的文件启动数据库。
    dtgxx
        6
    dtgxx  
    OP
       Jul 29, 2020
    @jiangzhuo #5 你这个建议蛮不错的,以后遇到需求感觉可以这么试试,挺好。只是目前这部分数据价格比较高买的,不太想放到别人服务器。
    594duck
        7
    594duck  
       Jul 29, 2020 via iPhone
    就不能先倒入关系数据库,再处理好所有的逻辑。死磕那个干嘛
    billlee
        8
    billlee  
       Jul 29, 2020
    你导进去要干嘛?这样即使能导完用起来还是会很慢啊
    dtgxx
        9
    dtgxx  
    OP
       Jul 30, 2020
    @billlee #8 查询用,之前不加联合索引是查询是很快的,两百亿数据查询,差不多 50ms 就能返回。
    dtgxx
        10
    dtgxx  
    OP
       Jul 30, 2020
    @594duck #7 主要是目前只有一个机器,用关系型数据库会比 mongo 慢更多。mongo 不用联合索引每秒我这可以处理到大约 50 万条数据,关系型数据库单点的肯定做不到。
    zxlzy
        11
    zxlzy  
       Jul 30, 2020 via Android
    @dtgxx 他这个建议是最靠谱的了,至于数据价格贵…… 多少大中小互联网公司生死存亡的数据都放在阿里云和 aws 上了。
    entertainyou
        12
    entertainyou  
       Jul 30, 2020 via Android
    分表?
    594duck
        13
    594duck  
       Jul 30, 2020 via iPhone
    @dtgxx 200 亿 50ms 返回?纯文本文件 200 亿行,grep 一下中间的文件,50ms 都回不了。

    要么你这技术已经很到家了,要么我淘汰了
    showhand
        14
    showhand  
       Jul 30, 2020 via iPhone
    是不是先读取索引数据,把重复的记下来,然后导入的时候判断下数据是否在重复的索引里面
    wupher
        15
    wupher  
       Jul 30, 2020
    索引无非是为了方便查询,你可以在查询函数上做文章,查询多条记录后,再返回你想要的唯一记录,或者通过逻辑字段来标识删除,都是可以的。

    唯一性索引本来就很影响性能,数据,建议谨慎使用。几百亿数据,正常都应该 sharding 了,更不建议使用唯一性索引。

    5 楼的建议也相当棒,买机器来处理也是条思路。
    dtgxx
        16
    dtgxx  
    OP
       Jul 30, 2020
    @zxlzy #11 放阿里云 aws 基本都是民口的。
    JCZ2MkKb5S8ZX9pq
        17
    JCZ2MkKb5S8ZX9pq  
       Jul 30, 2020
    需求没看很懂,唯一索引是建一个单独的字段,还是 createIndex ?
    如果碰到重复,处理逻辑是什么样的?

    另外有个比较基本的差别,insert_many 比逐条插入要快很多。可以考虑先 createIndex 然后批量导入,最后再说处理重复,不知道能不能行。
    dtgxx
        18
    dtgxx  
    OP
       Jul 30, 2020
    @wupher #15 确实是,感觉之前的不使用索引的方式也可以,只是下游取的时候得自己做去重了,而且增量订阅的时候,每次更新的数据量也越来越大了。
    dtgxx
        19
    dtgxx  
    OP
       Jul 30, 2020
    @JCZ2MkKb5S8ZX9pq #17 三个字段的联合索引,目前使用 mongoinsert 导入数据,insert_one 和 insert_many 都比较慢,都放弃了。重复数据保留任何一条就可以了。
    deep89381
        20
    deep89381  
       Jul 30, 2020 via Android
    用 mongoimport 导入 csv 或 tsv,重复数据会自动跳过的
    dtgxx
        21
    dtgxx  
    OP
       Jul 30, 2020
    @zhuifeng1017 #20 啊 大佬,这个哪里有说明吗,真是这样就太好啦
    JCZ2MkKb5S8ZX9pq
        22
    JCZ2MkKb5S8ZX9pq  
       Jul 30, 2020
    @dtgxx 20 楼说的看了眼,学到了。但感觉不管哪种去重,查找的花销总归是难免的,不如先全部丢进去再说了。可以以后慢慢处理。

    > 但是联合唯一索引在导入数据之后有重复数据就无法创建了
    这个没有看懂,如果是 mongo 自带的 index 不是可以重复的吗?
    windyland
        23
    windyland  
       Jul 30, 2020 via Android
    所以为什么不试试阿里云开内存盘呢。。。。。。?
    dtgxx
        24
    dtgxx  
    OP
       Jul 30, 2020
    @JCZ2MkKb5S8ZX9pq #22 先导入数据,然后添加唯一索引,被索引的字段如果有重复,这个索引就会建失败。
    JCZ2MkKb5S8ZX9pq
        25
    JCZ2MkKb5S8ZX9pq  
       Jul 30, 2020
    @dtgxx 是用

    createIndex({name:1,gender:1,age:1})
    如果是这种是可以重复的吧?

    加了{unique: true}的话倒不清楚,没用过这个,查询会更快吗?
    我去试试看这个。

    也可以考虑初期先导入,用起来再说,日后慢慢去重做 unique 吧。
    dtgxx
        26
    dtgxx  
    OP
       Jul 30, 2020
    @JCZ2MkKb5S8ZX9pq #25 联合唯一索引,唯一指的就是 unique 。
    JCZ2MkKb5S8ZX9pq
        27
    JCZ2MkKb5S8ZX9pq  
       Jul 30, 2020   ❤️ 1
    @dtgxx 嗯,看了下的确没有先 compound 然后再转换的方法。那就等于全部数据要预处理,那是怎么都快不起来了。
    去重的话感觉也是先建非 unique 的 index,然后排序去重能快一点。不过你这个量是满夸张的。
    wupher
        28
    wupher  
       Jul 30, 2020   ❤️ 1
    只有单条重复性不多的情况可以用这种方法。

    如果单条数据重复数量级很大,那就不适合了。

    几百亿也可以考虑放 ES 或者 Cassandra
    dtgxx
        29
    dtgxx  
    OP
       Jul 30, 2020
    @zhuifeng1017 #20
    引用:用 mongoimport 导入 csv 或 tsv,重复数据会自动跳过的
    这个你自己试过吗?我刚测试了,并不可以。

    @wupher 是 之前考虑用分布式大数据存储之类的,最终机器限制,就没搞。
    joApioVVx4M4X6Rf
        30
    joApioVVx4M4X6Rf  
       Jul 30, 2020
    假设数据有 500 亿。
    首先对数据对三个联合主键做一个取余,假设是模 10000,这样数据被分成了 10000 份,平均每份 500w 数据,所以只需要对这 500w 数据去重就行了,做好后直接插入数据库,不用建立唯一索引
    smallgoogle
        31
    smallgoogle  
       Jul 30, 2020
    哎。别说了。才弄完。5 亿数据。
    dtgxx
        32
    dtgxx  
    OP
       Jul 30, 2020
    @v2exblog #30 没太明白,把数据分成 1 万份,不也需要每一份都去重吗。
    @smallgoogle 共勉老铁。
    kuafou
        33
    kuafou  
       Aug 8, 2020
    @dtgxx 问题解决了吗?
    dtgxx
        34
    dtgxx  
    OP
       Aug 8, 2020
    @kuafou #33 只能导入之后,去重,再建索引,去重也非常慢,不过目前没有别的好办法。去重虽然慢,但是要远远快于提前建好索引的情况。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   810 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 58ms · UTC 22:13 · PVG 06:13 · LAX 15:13 · JFK 18:13
    ♥ Do have faith in what you're doing.