java处理亿级数据问题

心事讲给大风听 发布于 09/21 14:12
阅读 2K+
收藏 1

需求:从表a查出数据存入表b里

目前表a有4亿左右数据量,关键字段是手机号和c字段,手机号有重复,然后把从表a里查出的每一条数跟表b里的手机号字段进行比较,如果手机号重复则更新c字段,如果没有就新增到表b里

目前做法: 写了一个while循环,每一次循环从表a里取3000条数据,在把3000条数据进行循环,拿到每一条数据查表b进行依次比较新增或修改

测了一下这种方式处理数据效率太低了,for循环每循环一次就需要查库和改库,有没有一种更好的方式来解决这个问题?请指教

以下是问题补充:

@Kendlowski:多线程,多机器,别一次查一条 (09/22 09:49)
@亭舸翁:弄个redis,4亿条手机号占不了多少空间。都算完了再batch insert到库里 (09/22 12:27)
加载中
0
sprouting
sprouting

上es,这么大的数据量,查询全部走es,然后根据主键进行更新操作

0
逆风扬
逆风扬

增加一个时间戳字段,每次增量处理,直接使用数据库技术对比a表和b表:先做更新操作,然后在做插入操作。

0
木九天
木九天

手机号做唯一键,直接把A表数据新增或更新到B表

0
快乐and小猪
快乐and小猪

根据最大id做区间分隔[1,1亿] 可以按1w步长切分为 1w份任务,然后多机器多线程取任务,去做任务

0
星爷
星爷

根据手机号批量查询a  b 中的手机号 和 c字段  然后程序直接对比 是新增还是 更新。批量操作回去就行。

0
wei2011
wei2011

用replace into更新插入,多线程,分批提交,比如每个线程执行3000条再提交一次事务

0
fat-rabbit
fat-rabbit

数据库的问题还是在数据库层面想办法

1,如果数据库是Oracle,以上以为可以用 merge into做

2,如果数据库是Mysql,需要拆分两步

- update set A.c = XXX A, (select phone from B) where A.phone = B.phone

- into B select XXX from A where A.phone not in (XXX)

0
z
zb79463626

1. 全部加载到Set或者Map里面,然后进行对比(几千万数据非常非常快,具体时间忘了,应该在几秒之内)

2. 差异数据生成批量更新SQL

3. 批量执行SQL,批量大小看数据库性能,可以先试试5000条

这样性能瓶颈完全在3,如果是mysql的话,可以改刷盘参数显著提升性能。

0
梦里蓝天
梦里蓝天

我的想法,1使用left join 联合查出 a b表的数据,这样手机号没有在b的,b表的字段没有值,可以使用a.id > * and a.id < *;多查点。

2.循环查出来的数据判断是不是b表字段有值,以手机号为key放入set,有值得1,没有的0,并且过滤了重复的手机号,如果平均2个是一样的这样直接4亿变2亿了。

3.根据set插入数据或者修改数据

OSCHINA
登录后可查看更多优质内容
返回顶部
顶部