天天看点

Delete时小心子查询(F_BASE 语句执行时间过长) SQL优化

问题说明: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)
​