一个exists取代in的例子(分析两个执行计划的差别)

感受一些哪个sql更顺眼一些。SQL 优化HASH JOIN SEMI

案例:
LATCH 严重,主机CPU IDLE<10%(应该说明是那种类别的latch争用严重
绑定变量已经被实际值替换
select groupinsta0_.MEMBER_ID        as MEMBER1_33_,
      groupinsta0_.LIFE_CYCLE_ID    as LIFE2_33_,
      groupinsta0_.SERV_ID          as SERV3_33_,
      groupinsta0_.GROUP_ID        as GROUP4_33_,
      groupinsta0_.MEMBER_DESC      as MEMBER5_33_,
      groupinsta0_.MEMBER_TYPE_ID  as MEMBER6_33_,
      groupinsta0_.MEMBER_ROLE_ID  as MEMBER7_33_,
      groupinsta0_.MEMBER_OBJECT_ID as MEMBER8_33_,
      groupinsta0_.ACC_NBR          as ACC9_33_,
      groupinsta0_.KENAN_FLAG      as KENAN10_33_
from zk.GROUP_INSTANCE_MEMBER groupinsta0_
where groupinsta0_.GROUP_ID = '18972206'
  and (groupinsta0_.LIFE_CYCLE_ID in
      (select lifecycle1_.LIFE_CYCLE_ID
          from zk.LIFE_CYCLE lifecycle1_
          where lifecycle1_.EXP_DATE >= sysdate));

ID Operation                                           OBJECT_NAME                                  COST    CARD    BYTES                  
[00] SELECT STATEMENT                                                                                   227                                                                    
[01] HASH JOIN                                                                                                  227      132       8712  
[02]    TABLE ACCESS BY INDEX ROWID GROUP_INSTANCE_MEMBER                133      132       6864                          
[03]      INDEX RANGE SCAN                    I_FKK_GROUP_INSTANCE_ 270           3          135        
[02]    TABLE ACCESS BY INDEX ROWID LIFE_CYCLE                                         2      11890452 166466328
[03]      INDEX RANGE SCAN                    IDX_LIFE_CYCLE_EXP_DATE               1        96
(注意:不细看,这个执行计划是完美的。因此,我们在分析执行计划的时候,要详细的结合实际的SQL语句和统计信息,对执行计划进行分析。)

一看就是select lifecycle1_.LIFE_CYCLE_ID from zk.LIFE_CYCLE lifecycle1_ where lifecycle1_.EXP_DATE >= sysdate
返回的结果集太大,导致latch: cache buffers chains


但从执行上看HASH JOIN 的适合的情况是遇到一大一小两个结果集,条件groupinsta0_.GROUP_ID = '18972206' 的结果集才2条,而lifecycle1_.EXP_DATE >= sysdate 的结果集超过1KW


注意(分析的有些问题,我们只是关注两个执行计划,还是有很大的改进)。

目地让执行计划中HASH JOIN 为HASH JOIN SEMI
改写SQL如下:
select groupinsta0_.MEMBER_ID        as MEMBER1_33_,
      groupinsta0_.LIFE_CYCLE_ID    as LIFE2_33_,
      groupinsta0_.SERV_ID          as SERV3_33_,
      groupinsta0_.GROUP_ID        as GROUP4_33_,
      groupinsta0_.MEMBER_DESC      as MEMBER5_33_,
      groupinsta0_.MEMBER_TYPE_ID  as MEMBER6_33_,
      groupinsta0_.MEMBER_ROLE_ID  as MEMBER7_33_,
      groupinsta0_.MEMBER_OBJECT_ID as MEMBER8_33_,
      groupinsta0_.ACC_NBR          as ACC9_33_,
      groupinsta0_.KENAN_FLAG      as KENAN10_33_
from zk.GROUP_INSTANCE_MEMBER groupinsta0_
where groupinsta0_.GROUP_ID = '18972905'
  and exists (select 'x'
          from zk.LIFE_CYCLE lifecycle1_
          where lifecycle1_.EXP_DATE >= sysdate and groupinsta0_.LIFE_CYCLE_ID=lifecycle1_.LIFE_CYCLE_ID);

Elapsed: 00:00:09.65
ID Operation                                          OBJECT_NAME                        COST    CARD    BYTES                  
[00] SELECT STATEMENT                                                                        227                                                                    
[01] HASH JOIN  SEMI                                                                            227  132    8712  
[02]    TABLE ACCESS BY INDEX ROWID GROUP_INSTANCE_MEMBER    133  132    6864                          
[03]      INDEX RANGE SCAN                I_FKK_GROUP_INSTANCE_270    3    135        
[02]    TABLE ACCESS BY INDEX ROWID LIFE_CYCLE                              2    11890452 166466328
[03]      INDEX RANGE SCAN              IDX_LIFE_CYCLE_EXP_DATE        1    96  

标签: 暂无标签
oraunix

写了 199 篇文章,拥有财富 1026,被 339 人关注

转播转播 分享分享 分享淘帖
回复

使用道具

成为第一个吐槽的人

您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

意见
反馈