mysql 2个表数据同步 优化
最后111 2016-10-13 12:25:58 有2个表user 和user_temp 。字段一样(open_id ,name , sex)。open_id是主键,两个表的数据都比较大。 user表200w ,user_temp表100w左右。
假设user表中有如下数据:
open_id name sex
001 张一 1
002 李二 0
003 张三 1
004 张四 1
user_temp表中有如下数据:
open_id name sex
001 张修改 0
002 李修改 1
005 王五 1
006 王六 0
现在将这2张表的数据进行合并。 合并规则为:
1) 将user表中open_id 为001 ,002的数据,update为user_temp中的数据。
2) 将user_temp表中open_id 为005 ,006的数据,insert到user表。
3) 将user表中open_id 为003 ,004的数据,delete。
想要达到的效果为:
user表中数据改为如下:
open_id name sex
001 张修改 0
002 李修改 1
005 王五 1
006 王六 0
用了如下2个方法:
方法一:
1)
update user u inner join user_temp as tmp on tmp.open_id = u.open_id
set u.name = tmp.name , u.sex = tmp.sex,
2)
insert into user (open_id, name, sex)
select open_id, name, sex from user_temp tmp
WHERE not EXISTS (SELECT 1 FROM user u where u.open_id = tmp.open_id)
3)
delete from user u
where not EXISTS ( select 1 from user_temp tmp where tmp.open_id = u.open_id )
方法二:
写存储过程,先把需要update的数据全部查询出来,然后一条一条修改
CREATE PROCEDURE `update`()
BEGIN
declare NAME varchar(1000);
declare OPEN_ID varchar(255);
declare SEX varchar(1);
declare stop int default 0;
declare user_cur cursor for( SELECT ft.name, ft.open_id, ft.sex,
from user_temp ft where EXISTS ( select 1 from user f where f.open_id = ft.open_id )
);
declare CONTINUE HANDLER FOR SQLSTATE '02000' SET stop = null;
OPEN user_cur ;
FETCH user_cur INTO NAME , OPEN_ID, SEX;
WHILE ( stop is not null) DO
update user f set f.name = NAME , f.sex = SEX where f.open_id = OPEN_ID;
FETCH user_cur INTO NAME , OPEN_ID, SEX;
END WHILE;
CLOSE user_cur ;
END
后面还有2个存储过程略。。。。
以上2个方法都能实现功能。但是都存在问题,
使用 【方法一】 会造成长时间的锁表 (200w + 100w 数据join) 。
使用 【方法二】 执行速度太慢了, 执行完成需要几个小时。
求一个好的解决方案, 即 不会长时间锁表, 执行速度又不会太慢。