一张表 A ,数据量 1.4 亿,一张表 B ,数据量 1 千 3 百万。更新语句 update A set A.cola=(select colb from B where A.colc=B.cold) where exists (select 1 from B where A.colc=B.cold and colb is not null) 这是我目前能想到的语句了...如何优化呢,链接字段都有索引
1
ecloud 2022-07-21 16:57:38 +08:00
我印象中判断 null/not null 非常消耗性能,你看能不能把 null 给个缺省值
|
2
morty0 2022-07-21 16:59:17 +08:00
分片更新
|
3
wxf666 2022-07-21 17:08:53 +08:00
这样?语句等价不?
update A join B on A.colc = B.cold and B.colb is not null set A.cola = B.colb |
4
yangxx 2022-07-21 17:22:18 +08:00
分批次更新,根据 id 分几批去更新
|
5
L0L 2022-07-21 17:33:21 +08:00
查出来,然后批次更新吧;不然这样压力全在数据库,万一单点的库,万一堵塞,服务直接不能用了。
|
6
wxf666 2022-07-21 17:43:17 +08:00
|
7
gy123 2022-07-21 18:13:56 +08:00
@wxf666 可以用 limit 限制每次更新直到全部更新~因为你这么大数据量直接更新是个大事务,不走主键和索引甚至会造成长时间锁表...还是分批吧
|
8
v2eb 2022-07-21 18:29:21 +08:00 via Android
第一个子查询换 join 连接
第二个子查询代码层判断 本地测试下分批处理的单次耗时和总计耗时 |
9
v2eb 2022-07-21 18:33:11 +08:00 via Android
其他索引列多嘛, 能不能批量删除再新增
|
10
cmxzj OP 如果想完成操作最快的方法能是啥,不用考虑其他服务使用这个表的情况,想知道最快的操作。当然没有权限 disable 各种 log 就是
|
11
guisheng 2022-07-21 18:44:50 +08:00 via iPhone
查出来批次修改。批次查批次更新。
|
12
wxf666 2022-07-21 19:03:39 +08:00
|
14
wxf666 2022-07-21 19:24:47 +08:00
@v2eb 第二个子查询( select 1 from B where A.colc=B.cold and colb is not null ),
为什么不能在扫描表 B 的时候,顺带过滤掉呢? 难道是有 B.colb is not null ,某个索引就失效了吗? 按理说,表 B 是驱动表,应该是全表扫描的? 就算要分批查询,也应先过滤掉再取出来,而不是取出来再过滤掉? |
15
L0L 2022-07-21 19:49:50 +08:00
@wxf666 我也不是特别懂,实际还是要和不同类型的数据库有关系;平常用 Oracle 比较多,如果大批量更新的话,链接等待时长比较长,占用资源比较多;如果是有传输问题的话,比较稳定的逻辑场景的话,我会考虑使用简单的 produce 来做。
|
16
BoringBB 2022-07-21 20:18:26 +08:00
不确定下面那个写法是不是等价的
https://imgur.com/a/ZzGPngg |
17
liuhouer 2022-07-22 14:08:45 +08:00
这种场景利用 cdc 来做啊,现在大数据 cdc 的工具特别多
|