数据量太大 几百亿,但是只有一台机器,存储够用。
数据需要以三个字段建联合唯一索引。
如果不建索引,导入差不多一周就完事了。 但是联合唯一索引在导入数据之后有重复数据就无法创建了,去掉重复数据也非常的难。 建索引之后再导数据,非常非常非常的慢,可能是索引影响了插入速度。。
大佬们有啥高招吗
1
wupher 2020-07-29 21:01:54 +08:00
那就不要用唯一性索引
|
3
abcbuzhiming 2020-07-29 22:29:24 +08:00
不能自己写程序读取数据,然后在去重的基础上导入吗?无非就是慢一点呗
|
4
dtgxx OP @abcbuzhiming #3 写了很多程序,也做了非常多的优化,慢的不行。。数据量太大,程序无法支持去重的。
|
5
jiangzhuo 2020-07-29 22:37:47 +08:00 1
去阿里云 AWS 之类的开一套高性能的机器,导入,然后关闭数据库,把导入好的文件传回你那台机器,用导好的文件启动数据库。
|
6
dtgxx OP @jiangzhuo #5 你这个建议蛮不错的,以后遇到需求感觉可以这么试试,挺好。只是目前这部分数据价格比较高买的,不太想放到别人服务器。
|
7
594duck 2020-07-29 23:08:48 +08:00 via iPhone
就不能先倒入关系数据库,再处理好所有的逻辑。死磕那个干嘛
|
8
billlee 2020-07-29 23:23:23 +08:00
你导进去要干嘛?这样即使能导完用起来还是会很慢啊
|
10
dtgxx OP @594duck #7 主要是目前只有一个机器,用关系型数据库会比 mongo 慢更多。mongo 不用联合索引每秒我这可以处理到大约 50 万条数据,关系型数据库单点的肯定做不到。
|
11
zxlzy 2020-07-30 01:01:23 +08:00 via Android
@dtgxx 他这个建议是最靠谱的了,至于数据价格贵…… 多少大中小互联网公司生死存亡的数据都放在阿里云和 aws 上了。
|
12
entertainyou 2020-07-30 03:36:07 +08:00 via Android
分表?
|
13
594duck 2020-07-30 04:33:49 +08:00 via iPhone
|
14
showhand 2020-07-30 06:51:34 +08:00 via iPhone
是不是先读取索引数据,把重复的记下来,然后导入的时候判断下数据是否在重复的索引里面
|
15
wupher 2020-07-30 09:16:26 +08:00
索引无非是为了方便查询,你可以在查询函数上做文章,查询多条记录后,再返回你想要的唯一记录,或者通过逻辑字段来标识删除,都是可以的。
唯一性索引本来就很影响性能,数据,建议谨慎使用。几百亿数据,正常都应该 sharding 了,更不建议使用唯一性索引。 5 楼的建议也相当棒,买机器来处理也是条思路。 |
17
JCZ2MkKb5S8ZX9pq 2020-07-30 09:26:43 +08:00
需求没看很懂,唯一索引是建一个单独的字段,还是 createIndex ?
如果碰到重复,处理逻辑是什么样的? 另外有个比较基本的差别,insert_many 比逐条插入要快很多。可以考虑先 createIndex 然后批量导入,最后再说处理重复,不知道能不能行。 |
18
dtgxx OP @wupher #15 确实是,感觉之前的不使用索引的方式也可以,只是下游取的时候得自己做去重了,而且增量订阅的时候,每次更新的数据量也越来越大了。
|
19
dtgxx OP @JCZ2MkKb5S8ZX9pq #17 三个字段的联合索引,目前使用 mongoinsert 导入数据,insert_one 和 insert_many 都比较慢,都放弃了。重复数据保留任何一条就可以了。
|
20
zhuifeng1017 2020-07-30 09:37:54 +08:00 via Android
用 mongoimport 导入 csv 或 tsv,重复数据会自动跳过的
|
21
dtgxx OP @zhuifeng1017 #20 啊 大佬,这个哪里有说明吗,真是这样就太好啦
|
22
JCZ2MkKb5S8ZX9pq 2020-07-30 09:57:14 +08:00
@dtgxx 20 楼说的看了眼,学到了。但感觉不管哪种去重,查找的花销总归是难免的,不如先全部丢进去再说了。可以以后慢慢处理。
> 但是联合唯一索引在导入数据之后有重复数据就无法创建了 这个没有看懂,如果是 mongo 自带的 index 不是可以重复的吗? |
23
windyland 2020-07-30 10:00:26 +08:00 via Android
所以为什么不试试阿里云开内存盘呢。。。。。。?
|
24
dtgxx OP @JCZ2MkKb5S8ZX9pq #22 先导入数据,然后添加唯一索引,被索引的字段如果有重复,这个索引就会建失败。
|
25
JCZ2MkKb5S8ZX9pq 2020-07-30 10:14:04 +08:00
@dtgxx 是用
createIndex({name:1,gender:1,age:1}) 如果是这种是可以重复的吧? 加了{unique: true}的话倒不清楚,没用过这个,查询会更快吗? 我去试试看这个。 也可以考虑初期先导入,用起来再说,日后慢慢去重做 unique 吧。 |
26
dtgxx OP @JCZ2MkKb5S8ZX9pq #25 联合唯一索引,唯一指的就是 unique 。
|
27
JCZ2MkKb5S8ZX9pq 2020-07-30 10:32:27 +08:00 1
@dtgxx 嗯,看了下的确没有先 compound 然后再转换的方法。那就等于全部数据要预处理,那是怎么都快不起来了。
去重的话感觉也是先建非 unique 的 index,然后排序去重能快一点。不过你这个量是满夸张的。 |
28
wupher 2020-07-30 11:08:55 +08:00 1
只有单条重复性不多的情况可以用这种方法。
如果单条数据重复数量级很大,那就不适合了。 几百亿也可以考虑放 ES 或者 Cassandra |
29
dtgxx OP @zhuifeng1017 #20
引用:用 mongoimport 导入 csv 或 tsv,重复数据会自动跳过的 这个你自己试过吗?我刚测试了,并不可以。 @wupher 是 之前考虑用分布式大数据存储之类的,最终机器限制,就没搞。 |
30
joApioVVx4M4X6Rf 2020-07-30 18:07:53 +08:00
假设数据有 500 亿。
首先对数据对三个联合主键做一个取余,假设是模 10000,这样数据被分成了 10000 份,平均每份 500w 数据,所以只需要对这 500w 数据去重就行了,做好后直接插入数据库,不用建立唯一索引 |
31
smallgoogle 2020-07-30 18:36:35 +08:00
哎。别说了。才弄完。5 亿数据。
|
32
dtgxx OP |