问题说明:MySQL带子查询的delete或update会存在全表扫描,
MySQL5.5的子查询普遍存在的问题
MySQL5.7虽然已进行了优化,但是带子查询的Update、Delete仍存在问题
问题说明:MySQL带子查询的delete或update会存在全表扫描, MySQL5.5的子查询普遍存在的问题 MySQL5.7虽然已进行了优化,但是带子查询的Update、Delete仍存在问题
1.现象
F_BASE学习库在清理临时表时,模拟从500万数据中删除5万数据,执行时间超过一天还没有结束,导致功能无法投产。
问题语句:
delete
from base_center.ref_payee_bank_info_temp
where concat(account_no,account_name,bank_no) in
(select concat(arccno,raccname,obnkcode)
from fbase_center.ref_sffhbpma_bat
where betradtype = 2
and bensndrevf = '6'
and substr(bemsgtype,1,8) = 'BEPS.121'
and busscode = 'A105'
and bestatus in (36,37,39,40,41)
)
原因分析
使用explain查看执行计划时,发现虽然子查询存在主键,但是在执行计划为全表扫描,导致耗时剧增。
该问题在MySQL5.5时普遍存在问题,虽然MySQL5.7进行了一定优化,但是效果不是很明显
解决办法
针对子查询,采取delete from inner join的方式将子查询改为join,以进行优化,从500万条记录中删除,耗时13秒;即模拟真实场景从3500万条数据中(生产上7天的量),删除7万条数据,耗时也只需18秒多。
修改后语句为:
delete
from base_center.ref_payee_bank_info_temp AS a
INNER JOIN fbase_center.ref_sffhbpma_bat AS b
where a.account_no = b.raccno
and a.account_name = b.raccname
and a.bank_no = b.obnkcode
and b.betradtype = 2
and b.bensndrevf = '6'
and b.substr(bemsgtype,1,8) = 'BEPS.121'
and b.busscode = 'A105'
and b.bestatus in (36,37,39,40,41)