大表更新大表的建议方案

【 使用环境 】 测试环境
【 OB or 其他组件 】
【 使用版本 】OceanBase 4.3.5.5 (r105070022026031722-0639a4b5e9af1dae33bff3fefac15c3b62ae5571) (Built Mar 17 2026 22:56:58)
【问题描述】
有两个大表 table_a,table_b,分别都是千万级的数据,现在需要用table_a的col_1,col_2,col_3字段关联table_b的col_1,col_2,col_3字段,并把table_b对应的amount字段更新到table_a.

请问这种需求,怎么做性能最好? 尝试直接更新,会卡住很久也跑不完.

3 个赞

– 假设存在一个自增主键 id,每次更新 50,000 条
SET t_min = (SELECT MIN(id) FROM table_a);
SET t_max = (SELECT MAX(id) FROM table_a);

WHILE t_min <= t_max DO
UPDATE /*+ PARALLEL(4) */ table_a t1
JOIN table_b t2
ON t1.col_1 = t2.col_1 AND t1.col_2 = t2.col_2 AND t1.col_3 = t2.col_3
SET t1.amount = t2.amount
WHERE t1.id >= t_min AND t1.id < t_min + 50000;

COMMIT;
SET t_min = t_min + 50000;
END WHILE;

2 个赞

nbjojv33952

buff896325

gbnkjy25836

可以分批提交,大事务拆掉为小事务。

1 个赞

是不是可以对大表进行分区,分区放在不同的机器上,分布式执行呢

1 个赞

– table_a 联合索引(关联字段)
CREATE INDEX idx_a_3cols ON table_a (col_1, col_2, col_3);

– table_b 联合索引(关联字段 + 覆盖索引)
CREATE INDEX idx_b_3cols_amount ON table_b (col_1, col_2, col_3, amount);
table_b 加了 amount 变成覆盖索引,不用回表查数据

1 个赞

切记不要想着一个语句更新完可以考虑 JOIN 生成新表 + RENAME,或 旁路导入或者 tmp 映射表 + 按 PK 分批 UPDATE