服务器中每天会上传一个 txt 格式的人员清单(应该每天就几万条),为了和数据库中的人员保持一致,需要按行逐一读取与数据库对比,比如数据重复,数据不存在等。。。 个人感觉逐一对比这种方式过于复杂,每读取一行就要遍历一次用户表的数据,请问还有其他效率更高,更简单的方法处理吗?
1
renmu123 2022-05-31 17:51:07 +08:00 via Android
都拿出来放到内存里来比
|
2
Geekerstar 2022-05-31 17:51:22 +08:00
数据库中数据不多的话,查关键字段到内存后,与 txt 取差集
|
3
lybcyd 2022-05-31 17:53:41 +08:00
就几万条,量也不大,直接把数据库数据读成一个 k-v 的 map ,再把 txt 的数据读入一个 list ,直接检查 key 是否存在
|
4
Joker123456789 2022-05-31 17:54:34 +08:00
设置一个 唯一约束的字段,插入的时候报错 就说明存在了。
|
5
zx9481 OP |
6
Joker123456789 2022-05-31 17:56:32 +08:00
如果你只是想 过滤掉 存在的这条,也可以,用 on duplicate key update 就好了, 插入时发现唯一字段冲突了,就只做更新操作
|
7
bxtx999 2022-05-31 17:58:09 +08:00
bloom filter
|
8
liprais 2022-05-31 17:58:24 +08:00 2
几万条写到数据库里面一个 join 完事
|
9
Macolor21 2022-05-31 17:59:09 +08:00 1
1. 先查询所有用户表 /关键数据到内存 1 次网络 I/O
2. 放入 HashMap/ BloomFilter 3. 再读取 txt 的所有数据,构建出 List 1 次文件 IO 4. 遍历 list 比对数据 因为几万条的数据量也不大,假设特别大了,就考虑用 io 来换内存空间了。 |
10
lookStupiToForce 2022-05-31 18:30:58 +08:00
"每读取一行就要遍历一次用户表的数据"
不是,你数据库里那张表的 join_key 不建索引的吗,居然查一次就扫一次全表? 建索引后 b+tree 匹配一条数据就只用查几次而已,树深度通常就 3 撑死了就 4 ,查几次由深度决定 这样几万条记录进去 nested loop join 撑死也就查(几万*4)次而已,再慢再慢的 io 也就几秒钟,哪还用加上其他开发啊?除非你数据库非常繁忙,这几秒钟的 io 都要排队跟其他进程均分。 |
11
aec4d 2022-05-31 18:32:45 +08:00
数据库安装个 xxhash ,数据库和 csv 同时针对主键计算摘要
https://jolynch.github.io/posts/use_fast_data_algorithms/ |
12
ChoateYao 2022-05-31 19:27:03 +08:00
你需要找出不一致的数据,那么循环的少不了,只要你把数据都取出来放内存里面的话,对比还是很快的。
|
13
wowh 2022-05-31 20:05:08 +08:00 via iPhone
不知道是怎么对比?如果有唯一匹配字段的话 ,可以建个索引,直接读取数据库也不慢。
不方便修改数据库的话,也可以把数据库的数据都写到 redis 里,再匹配这样应该更快一些 |
14
yazinnnn 2022-05-31 20:06:10 +08:00
用 hashset 比较的话会很快吧
|
15
luozic 2022-05-31 21:14:15 +08:00
有木有名称重复,没有直接用 Cuckoo Filter
|
16
512357301 2022-05-31 22:52:52 +08:00 via Android
题主是 rd 吧,这种问题跟 dba 沟通下吧,这种数据量,这种逻辑对他们来说是小意思,你别乱来,否则得小心他提刀来见,哈哈哈。
其实我觉得#8 楼 @liprais 的方法不错 |
17
strawberryBug 2022-05-31 22:59:34 +08:00 via Android
redis sdiff
|