mysql 2个表数据同步 优化
有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) 。
使用 【方法二】 执行速度太慢了, 执行完成需要几个小时。
求一个好的解决方案, 即 不会长时间锁表, 执行速度又不会太慢。
假设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) 。
使用 【方法二】 执行速度太慢了, 执行完成需要几个小时。
求一个好的解决方案, 即 不会长时间锁表, 执行速度又不会太慢。
...全文
相关推荐
MySQL表数据迁移
2. **数据同步**:数据迁移不仅仅是简单的备份和恢复,也可能是实时或定期的数据同步。"datamove"或许能够同步两个MySQL实例之间的表数据,确保数据一致性。3.
SeaTunnel 2.3.12实战:5分钟搞定MySQL到ClickHouse的数据同步(附完整配置)
本文提供了一份基于SeaTunnel 2.3.12的实战指南,详细演示了如何快速构建从MySQL到ClickHouse的高性能数据同步管道。内容涵盖从环境准备、基础配置到实时增量同步(CDC)的完整步骤,并分享了生产级部署、性能调优与疑难排查的核心经验,帮助用户高效实现数据集成与分析。
MySQL到Doris数据同步配置[源码]
本文将重点介绍SeaTunnel 2.3.3版本在实现MySQL到Doris的全量和增量数据同步过程中所涉及的配置方法。
kettle 数据同步
Kettle支持详细的日志记录和监控,可以开启日志和审计功能,跟踪数据同步过程,便于问题排查和优化。六、自动化执行10.
canal-mysql-elasticsearch-sync20201010.rar
Canal支持多种模式,包括单表同步、多表同步,以及复杂的嵌套结构同步。2.


