用多线程的方式,将A表中的数据复制到相同结构的B表。
数据量很大,要求速度。
[code="java"]A表结构
ID,
NAME,
STATuS(复制到B表的状态)[/code]
问题是怎么能保证多线读A表的时候,不会读到重复的数据。
不能用同步关键字。当时没想出好的方法,不知道大家有什么好的思路没有。
举例子
1.搜索到1000条数据
2.根据ID进行hash运算,最简单方式取余
3.根据hash运算以及你的CPU内核,execute创建线程池
4.然后根据hash运算后的结果,分配到不同线程
5.创建异步任务,任务submit
6.结束
瞎猜啊
在创建线程的时候 确定拷贝数据
你的这个问题,我在实际中做过,当时我是多线程创建solar索引,这个问题我的解决法很简单
取出数据总条目,使用分页查询,然后决定每个线程拷贝哪几页的数据就行了。当时我那个表的主键是自增的,使用主键id升序查询,一切OK
我看到你的条件是“保证多线读A表的时候,不会读到重复的数据”,
我觉得这个没法保证。除非像楼下strivezsh说的,每个线程确定读那块数据。
我的2种解决办法:
1、[code="java"]
BEGIN TRANSACTION --开始事务
//查询数据
select isread from A where id=@id and isread=0 for update nowait
//插入新表
insert into B values(id,name,status);
//更新原表状态
update A set isread=1 where id=@id
COMMIT TRANSACTION
[/code]
2、将数据读到java.util.concurrent.BlockingQueue中
多线程取出,然后插入B
写的也不是很完全,欢迎指正
1、建立一个线程安全的队列
2、新建一个线程,将从A表中查询的数据保存到队列中。
3、新建多个线程同时从队列中获得数据并插入B表(使用事务批量插入,例如1000条插入一次)
以上方法在oracle等插入时数据库为行锁时有用,如果为mysql(插入时表锁)多线程的效果就体现不出来了
先取出总条数,比如10 000 条
假设用10个线程,那就每个线程1000条数据
第一个线程复制1-1000
第二个线程复制1001 - 20001的
...
数据量很大,大到什么地步,这是关键啊,上亿,几十亿这种情况就不可能将数据全部加载到内存再来处理。
把A 表 的数据 复制到B表,insert into B(field...) select field... from B
这句SQL 就搞定啊,最后再来个更新 A表所有数据状态,
什么多线程,不管你多好的算法,都要把 数据加载到内在再插入到B表,速度快不了
同意wgy_superpower 的。
同数据库里操作,不管记录数多少,再多的,也不如数据库内部直接复制来得快。
果断select * from A into B 或insert into B as select * from A
我开发过这方面的应用。想高效率,高可靠性的完成数据的迁移,可以这样做:
一边读源数据库,一边插入数据到目标数据。
当然读的过程中,是把数据缓冲在阻塞队列中的,
然后让多线程去把数据插入到目标数据库。
可以达到5000--7000条/秒