一次SQL优化

 

前不久一位同事在做两个表关联更新,等了N久没执行出来,找我帮他看是什么原因。他的更新语句如下

update  dsamerr201109 a

  set (a.opr_status, a.new_result, a.unique_no6, a.unique_no7, renew_time)= (select '1',

                                                                                     note_info,

                                                                                     function_attr5,

                                                                                     function_attr6,

                                                                                      sysdateup_date

                                                                                from dmcs.edmcsattributeday_suess b

                                                                               where  b.collect_day =

                                                                                     '20110919'

                                                                                 and b.renew_flag = '1'

                                                                                  and  a.id = to_char(b.stream_id))

执行计划

    update

          indexfullscan   ind_dsamerr201109 

         table access full      edmcsattributeday_suess

他在a表的id字段上建了一个索引,但是我看执行计划并没有走索引,我在update后面加上index hint后,还是没有变化,任然没有走索引,后面在网上搜索了一下,查阅了相关的资料,发现是因为建表时id字段设置的是允许为空(nullable)的,这样会导致索引失效,修改为不为空后,执行计划发生了变化

出现了索引全扫描,但是任然是等待N久也没法更新完成,分析是因为这个索引全扫描会有回表操作,跟之前的执行效果差不多,仔细分析他的SQL语句后,发现他的SQL存在问题,对关联不上的记录会被置空,我在最后加上了一句

where exists(select 1 fromdmcs.edmcsattributeday_suess c where a.id=to_char(c.stream_id))

执行计划

     update

          nested loop

               sort unique

                    table aceess full      edmcsattributeday_suess

                index range scan       dsamerr201109
         table access full              edmcsattributeday_suess

再看执行计划发生了明显变化,对A表执行的是索引范围扫描了,执行成本和IO都得到了大幅下降执行效果也证实了这一点,仅用0.09s就完成了update。

总结

1、  建索引的字段不能设置为nullable,否则不会走索引

2、  索引全扫描的回表操作会导致性能下降

3、  编写SQL语句时要仔细分析,尤其是多表的连接操作



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值