1
T0m008 2023-05-09 06:31:17 +08:00
是要找出来还是就去掉重复的就行了?
去掉重复的话就很简单了。 |
2
lzz2394677796 OP 是要找出来
|
3
levelworm 2023-05-09 06:43:27 +08:00
https://stackoverflow.com/questions/47095438/get-duplicate-records-from-a-large-table
不知道回答中的方法速度如何,不知道的确是你需要的。 |
4
lzz2394677796 OP 左手同事说,用 256g 内存进 redis 排查会快,什么意思?
|
5
optional 2023-05-09 07:00:07 +08:00 via iPhone
最后一通操作,还不如直接 group by count>1
|
6
billgong 2023-05-09 07:15:43 +08:00 via iPhone
@lzz2394677796 那就和 mysql 没关系了,属于把数据读进内存然后再排查。redis 是内存数据库,速度当然快得多。但你得有条件(相当大的内存)才能跑得起装这么多数据的 redis 嘛,变相相当于蛮力跑了。
|
7
qiayue 2023-05-09 07:53:39 +08:00
分清楚是考察思维还是真实需求。
如果是真实需求场景,一般在 10 亿级别的数据,肯定是分库分表了,那么找出重复的几条,这种属于鸡蛋里挑骨头的需求,建议不做。因为得不偿失,相对于去掉重复的几条之后的好处,需要花费的代价太大,所以根本没必要做。 |
8
neptuno 2023-05-09 08:09:25 +08:00 via iPhone
布隆过滤器试试
|
9
lzz2394677796 OP @qiayue 是 1 亿条一个表,确切总量约 50 亿,蛮力也可以,只要找出来
|
10
djoiwhud 2023-05-09 08:26:24 +08:00 via Android
不知道我理解得对不对。
没有保存手机明文?保存了就应该换加密方式。而不是试图剔除出碰撞的记录。 |
11
lzz2394677796 OP @billgong 用 getsizeof 测算过内存开销,约 256g 能放进
|
12
shakoon 2023-05-09 08:36:46 +08:00 1
歪个话题。50 亿条手机号,全中国也没这么多。真收集了上亿手机号的企业,应该不会出现这种问题,不然这系统得多烂啊。所以,这真不是一个作业题?
|
13
netnr 2023-05-09 08:48:33 +08:00 via Android 1
最近接触 ClickHouse 写入 1.5 亿日志,分批 100W/5s 写入速度,平均 20W/s
50 亿大概要 7 小时,后面再查询统计就没得心智负担了,从根本上解决问题 只是提供一个参考,不一定适合你们的业务 |
14
HunterPan 2023-05-09 08:51:16 +08:00
roarinmap
|
15
scemsjyd 2023-05-09 08:56:28 +08:00 via iPhone
使用不同的哈希函数进行多次布隆过滤
假如进行 10 次布隆过滤 10 次结果中都存在的大概率重复 个人想法如有不对请指正 |
16
hhjswf 2023-05-09 09:11:26 +08:00 via Android
允许误差吗?可以的话,用布隆过滤器?
|
17
H0H 2023-05-09 09:39:34 +08:00
这种有啥难的。这一看就是只要找出来处理掉即可,并没有要求实时的瞬间查询出结果。
1.从数据库把 10 亿数据读取到磁盘上(因为内存中可能放不下)的一个文件中。 2.根据装入内存大小限制,就这 1 个文件拆分成多个子文件。比如每个子文件存储 10 万条数据。 3.一次读取每个子文件到内存进行排序,调用默认的排序算法升序排序即可,并保存。 4.依次针对每 2 个子文件,一行行读取到内存执行归并排序,排序时找到了相同的行,就记录下来。 5.将记录下来的那些行,编写 SQL 脚本更新数据库 |
18
sujin190 2023-05-09 09:44:21 +08:00
@lzz2394677796 #9 50 亿 50 个表如果不是有序的话,group by 要连表估计难,其实最快的应该是用默认顺序读出来按序分堆到 5000 个文件,然后再单个文件处理找出重复就好了,如果内存充足的话直接读在内存算就好了啊,要啥 redis
|
19
happyn 2023-05-09 10:01:53 +08:00
不用那么麻烦,10 亿手机号,导出个 txt ;然后 就想楼上说的,多拆分几个子文件,分别排序再合并,最后用 uniq -d 查一下就可以;
脚本示例: split -l 1000000000 huge-file small-chunk for X in small-chunk*; do sort -u < $X > sorted-$X; done sort -u -m sorted-small-chunk* > sorted-huge-file && rm -rf small-chunk* sorted-small-chunk* cat sorted-huge-file|uniq -d |
20
happyn 2023-05-09 10:05:31 +08:00
脚本有点问题,修正下:
split -l 1000000000 huge-file small-chunk for X in small-chunk*; do sort -o sorted-$X $X; done sort -m sorted-small-chunk* > sorted-huge-file cat sorted-huge-file|uniq -d |
21
sadfQED2 2023-05-09 10:10:45 +08:00 via Android
你是需要实时计算还是仅仅需要找出来?如果只是为了找出胀数据,那直接去从库执行 select x,count(1) from table group by x having count(1)>1 不就完事了。
如果你需要线上业务实时计算的话,那就上实时计算引擎,比如楼上说的 clickhouse ,或者 starrocks 之类的。你这样业务,实时计算引擎能够几百毫秒出结果 |
22
amon 2023-05-09 10:24:11 +08:00
如果只为了找出来,group by having 即可。
如果是为了面试,请将你知道的所有技术名词试着用通顺的逻辑组合在一起即可。 |
23
mmuggle 2023-05-09 10:35:43 +08:00
bitmap
|
24
sujin190 2023-05-09 10:52:13 +08:00
|
25
swulling 2023-05-09 11:06:10 +08:00 via iPhone
dump 出来用 awk 一行就搞定了。时间复杂度是 O ( 1 )。不用 awk 随便找个语言用 HashMap 就行了。
用 sort 的不知道是咋想的。 |
26
JKeita 2023-05-09 11:09:27 +08:00
用 bitmap
|
27
Chad0000 2023-05-09 11:23:21 +08:00
如果只是偶尔需要排查的话,那么可以将 50 亿数据分组,比如按前两位字母。这样每次只算一组,直接在内存中计算,不需要那么大内存。
|
28
lzz2394677796 OP 不是面试。索引后总数据库文件约 300G 。
|