Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
3.9k views
in Technique[技术] by (71.8m points)

mysql如何高效快速整合两个表的内容?

需求

A表中有70万数据,B表中有50万数据。
现在要实现:
将B表导入A表。
A、B两个表中有一些重复数据,比如A表中有name='张三'这个字段,B表中也有name='张三'这个字段,则两个保留一个。若B表中有,A表中没有,则往A表中添加。

我的实现

while(B表中查出的数据不为空){
    //查询出B表中的数据
    //每次查询1000条B表中的数据,循环查询直到查询为空
    $data = selectFromB(1000);
    $needInsert = [];  //需要添加的数组
    for($data as $key=>$value){
        //判断该数据在A表中是否存在
        $existInA = isExistInA($value['name']);
        if($existInA == 0){  //在A表中不存在,则添加
            array_push($needInsert,$value);
        }
    }
    //将本次处理得到的需要添加的数据批量添加到A表
    batInsertToA($needInsert);
}

遇到的问题

中间那一步isExistInA(判断该数据在A表中是否存在)太耗时,每循环一遍都要去查一次库,导致将A、B整合完成都需要半个小时的时间。
请问这种问题如何优化?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

1、70W数据不多,一次性将A表的ID、NAME保存在内存里,然后批量读B表,判断重复数据。
2、写入数据的时候,批量写,例如一次写200条数据,性能会大大提高。
3、可以一边处理数据,一边写数据,即处理好了200条,就直接写入,不必等所有数据都处理好了,再写。
4、70W数据按ID排序,记住最后一次处理的ID,这样任务即使中途结束,不用重新开始。
5、别开事务。
6、找个凌晨3点执行任务。
7、B表的数据一次读1000条,太少了,可以读1W条,而且只读ID和NAME,这样筛选了符合条件的记录之后,可以:
insert into A select * from B where ID in (12,13,14)
如果B表的列很多,可以节省很多网络开销。

关注我的博客: https://www.epoooll.com/


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...