优化一个sql,就是有A,B两个表,要利用b表的字段更新a表对应的字段。形如

Sql代码  

  1. update A set A.a=(select B.b from B where A.id=B.id);  



原SQL

updatepntmall_rptpoint_detail a set a.scrm_rptpnt_processed=(

select distinctb.scrm_rptpnt_processed  frompntmall_rptpoint_detail_tmp b where a.pntmall_rptpnt_id=b.pntmall_rptpnt_id

);


b表中只有1条数据,a表中有37万条数据,应用逻辑为更新a表中id和b表相同的

这一条SQL执行了6小时未执行完,执行计划显示为全表扫描,也就是说,虽然执行1条SQl,但执行update个过程中将37万条数据进行扫描,直到倒找相同的id进行更新


尝试过hit强制走索引,也不理想,where条件中id列类型是相同的均为INT,不存在字段类型不同导致不走索引的情况。


采取的方式:

优化后的SQL

updatepntmall_rptpoint_detail a set a.scrm_rptpnt_processed=(

select distinctb.scrm_rptpnt_processed  frompntmall_rptpoint_detail_tmp b where a.pntmall_rptpnt_id=b.pntmall_rptpnt_id

) wherea.pntmall_rptpnt_id in (select b.pntmall_rptpnt_id frompntmall_rptpoint_detail_tmp b)


优化后的SQL达到秒级,满足客户需求。


总结一下不走索引的情况:

1、条件字段选择性弱,查出的结果集较大,不走索引;

2、where条件等号两边字段类型不同,不走索引;

3、优化器分析的统计信息陈旧也可能导致不走索引;

4、索引字段 is null 不走索引;

5、对于count(*)当索引字段有not null约束时走索引,否则不走索引;

6、like 后面的字符当首位为通配符时不走索引;

7、使用不等于操作符如:<>、!= 等不走索引;

8、索引字段前加了函数或参加了运算不走索引;