SQL语句优化,看到性能瓶颈。

     春日东风, 拂面无寒。 油菜花香,微风拂过泛起点点菜想。 每年此时哥应该在湖边, 望着悠悠水草,阵阵涟漪之中的浮漂。 

点点动作,便是激动上鱼时刻的前奏。 时间如水流飞逝, 却百无聊赖。 都会想到  我是谁, 我干什么的。

就在那时说说一个SQl优化吧。

INSERT INTO INST.A_CARD_NUMBER_BLACKLIST
  SELECT O.PARTY_ID,
         OS1.PROD_ID,
         OM.OFFER_ID,
         OS.OFFER_SPEC_ID,
         OS.STATUS_CD,
         SYSDATE
    FROM INST.OFFER_MEMBER OM,
         INST.OFFER        O,
         SPEC.OFFER_SPEC   OS,
         INST.OFFER_SERV   OS1
   WHERE OS1.PROD_ID IN (SELECT PROD_ID
                           FROM INST.OFFER_SERV
                          WHERE SERV_SPEC_ID = 1537
                            AND STATUS_CD = 12)
     AND OM.MEMBER_ID = OS1.SERV_ID
     AND OM.STATUS_CD = 12
     AND OM.OBJ_TYPE = 4
     AND OS.OFFER_SPEC_ID = O.OFFER_SPEC_ID
     AND OS.OFFER_SPEC_ID NOT IN (300500003485,
                                  300509027473,
                                  300006000633,
                                  300509027536,
                                  300006000639,
                                  300006000009,
                                  300006000020)
     AND OM.OFFER_ID = O.OFFER_ID
     AND OS1.STATUS_CD = 12
     AND OM.CREATE_DT >
         (SELECT MAX(VERSION) FROM INST.A_CARD_NUMBER_BLACKLIST)
  UNION
  SELECT O.PARTY_ID,
         OM.MEMBER_ID,
         OM.OFFER_ID,
         OS.OFFER_SPEC_ID,
         OS.STATUS_CD,
         SYSDATE
    FROM INST.OFFER_MEMBER OM, INST.OFFER O, SPEC.OFFER_SPEC OS
   WHERE OM.MEMBER_ID IN (SELECT PROD_ID
                            FROM INST.OFFER_SERV
                           WHERE SERV_SPEC_ID = 1537
                             AND STATUS_CD = 12)
     AND OM.STATUS_CD = 12
     AND OM.OBJ_TYPE = 2
     AND OS.OFFER_SPEC_ID = O.OFFER_SPEC_ID
     AND OS.OFFER_SPEC_ID NOT IN (300500003485,
                                  300509027473,
                                  300006000633,
                                  300509027536,
                                  300006000639,
                                  300006000009,
                                  300006000020)
     AND OM.OFFER_ID = O.OFFER_ID
     AND OM.CREATE_DT >

         (SELECT MAX(VERSION) FROM INST.A_CARD_NUMBER_BLACKLIST);

AWR 报告中一个SQl。 1小时执行不完。  分析SQL,哥发现主要是因为大表多次扫描导致, 有没有办法等价改写,把SQl中两次扫描变成一次呢?? 答案是肯定有办法的, 但是哥试着改写,发现下手确实困难。 算了想另外的办法把。

    OFFER_MEMBER OM   20G
         INST.OFFER      27G
         SPEC.OFFER_SPEC   OS, --- 小表

         INST.OFFER_SERV    17G

执行计划:


 

你能一眼看到性能瓶颈吗? 如果不能,你还需要修炼。 

       信不信有你,性能问题在id = 7,20 . 因为这个表是大表,全表扫描。 

      有人说性能问题在id = 1  sort union  . 这个去重操作, 执行计划中tempspc 到达1千多K, 另外还有cost 最高。 TIME这一步得耗费2小时。貌似很有道理, 但是哥说,如果“有人”从这一步下手了, 那“有人”优化还不过关, 需要修炼。 “有人”说错了, 大错特错。  为啥错?? 这个问题很简单,各位想想就通了,不说了。

 哥看到这个 id = 7,20 。根据rows不多。CBO 选择了子查询作为驱动表, NL 外面的大表。CBO很聪明。  

哥毫不犹豫的查询SQL。 SELECT   /*+  parallel(t,8) */ count(1)  FROM INST.OFFER_SERV t   WHERE SERV_SPEC_ID = 1537     AND STATUS_CD = 12;查询了5分钟。  题外问题为何哥开了8个并行? 另外如何查询SQL执行时候到底开了几个并行?  有没有想过类似问题? 8011 条数据。 

那哥更加确定了,肯定可以完美优化。 我知道你们认为是建索引, 的确建索引也是最好的办法, 但是问题在生产库,不和业务通知下就建索引?肯定不可行的。 哥可以建议建索引, 但是现在不要建索引优化。


那就用这个驱动表驱动下去,有人会问原来的也是这样的, 为啥会慢了?? 哥用的办法不同。


而且哥提醒, 不要随便在SQl中添加 并行, 哥在主要查询中特意把并行关了。 执行计划就不写了。  这样驱动表 只查询了一次

记好这个hints, 生产库中一时半会不能建索引,这招还真的管用。

猜猜看多久? 292S(没有建索引情况下) 。  1小时多没有执行完, (哥估计需要2小时20分钟)现在优化到 300S之内。    

意不意外?惊不惊喜?

那我的建议是  1 在表 OFFER_SERV 建索引,当然了, 你要考虑这两个 SERV_SPEC_ID, TATUS_CD , 那个在前面, 另外还需要考虑 PROD_ID 字段是否需要包含在索引中,以及在索引中的位置。  这个涉及数据库对象的设计了, 以后的文章慢慢说吧。

2 共同的驱动表提取出来,组成临时表, 临时表驱动下去......

那问题来了? 如果哥再一次提高性能咋办?(工作中优化后快了就行,不要纠结, 哥以前纠结过总想把SQl优化到极致,成本最小,效果最大,结果 同时服务3,4个项目组, 也就是 5,6个人问SQL如何优化, SQl如何写, 复杂PLSQL写优化, 等乱七八槽的问题 时候,你会发现根本来不及搞,  本身这个SQL优化, 如果说 哥不搞索引把SQL性能 提升了 50...多倍 , 还有谁不满意????  )

算了哥详细分析一下吧。


第11步走了一个索引, 很显然是OM的  member_id 的索引。 然后第10步回表再过滤,第10步的谓词条件中, 

我估摸这OM.CREATE_DT   这个条件,过滤数据最多的。 那如果哥建一个索引  OM(member_id ,CREATE_DT )

会咋样? 也就是说在不用回表就可以干掉大部分数据了。 所以就能优化SQL。  

各位想想看还有其他办法再次提高性能吗??


   就是回表访问的数据,放入索引中,减少回表, 那有没有其他办法再次提高性能呢??


哈,不知不觉把大家从优化SQL,带入到优化系统方面了。  根据索引 回表,就是其实就是离散IO, 而提高性能的办法也是减少离散IO的办法之一, 就是部分数据集中。( 没建索引之前,oracle是行存储的,也就是散乱的, 而我们建的组合索引, 也就是把需要的数据集中到一个标记对象中也就是索引中,)







猜你喜欢

转载自blog.csdn.net/daiqiulong2/article/details/79800680
今日推荐