阿里EDAS “小表广播”不能用的另一种实现总结

问题需求:

有两张表,一张是分库表tableA ,另一张是非分库表tableB,两张表机构如下:

tableA的bus_col_a 本来应该关联tableB的bus_col_b字段  现在关联成了id字段,

需要修改tableA表的部分数据(50万以下)的bus_col_a字段的值为tableB的bus_col_b字段的值,但是tableA表是分库表,数据量很大(2K万以上),tableB是非分库表,需要对tableB进行“小表广播”,可悲的是EDAS的小表广播不可用!!!

 

有的人可能会说,不就是简单的一句

UPDATE tablea a SET bus_col_a = (SELECT b.bus_col_b from tableb b where a.bus_col_a = b.id);

语句的事情那么简单的事情吗~  呵呵 那您可以试试了  肯定是不行的,会慢的要命的,你根部不知道什么时候能update操作结束。

应为是分库,那么你会想可以分库操作啊,不好意思  tableB表只一个库中有,别的库中都没有tableB表,所以你即使分库操作成功了 也只是修改了其中一个库的数据 别的库的数据还是没有修改的。

 

建表语句:

tableA:
CREATE TABLE `tablea` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `bus_col_a` int(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

tableB:
CREATE TABLE `tableb` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `bus_col_b` int(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 解决思路:

  考虑到需要修改的数据并不多,可以对每个需要修改的数据分库执行一个update语句来修改数据 例如:

       

UPDATE tablea SET bus_col_a = '1' where bus_col_a='10001'

 

操作步骤:

  1.将需要修改的数据提取出来:

INSERT INTO tablea_temp (id,user_id,bus_col_a) 
SELECT id,user_id,bus_col_a from tablea where+需要修改数据的条件

     2.生成需要修改的sql语句:

SELECT CONCAT('/!TDDL:SCAN AND MERGE_CONCURRENT=TRUE*/update tablea set bus_col_a=',bus_col_b,' where bus_col_a=',bus_col_a,';') from (
SELECT DISTINCT a.bus_col_a,b.bus_col_b from tablea a LEFT JOIN tableb b on a.bus_col_a = b.id
) as aa
/!TDDL:SCAN AND MERGE_CONCURRENT=TRUE*/  表示分库执行后面的sql语句

 3. 分库执行生成的sql 语句: 这下就快多了 ,如果被修改的字段建立了索引,那就快的不行不行的了

 

 

 

     

posted @ 2017-12-03 23:25  樊金龙  阅读(1661)  评论(0编辑  收藏  举报