使用临时表的sql优化案例一

基于RBO的情况下

[@more@]

oracle:9204

1.table和index的相关信息:

create global temporary table tmp_ic_atp_test1
(CTMPCORPID CHAR(4),
CTMPCALBODYID CHAR(20),
CINVENTORYID CHAR(20),
VFREE1 VARCHAR2(20),
VFREE2 VARCHAR2(20),
VFREE3 VARCHAR2(20) ,
VFREE4 VARCHAR2(20) ,
VFREE5 VARCHAR2(20) ,
VFREE6 VARCHAR2(20) ,
VFREE7 VARCHAR2(20) ,
VFREE8 VARCHAR2(20) ,
VFREE9 VARCHAR2(20) ,
VFREE10 VARCHAR2(20) ,
DPLANDATE CHAR(10) ,
USABLEAMOUNT CHAR(16) ,
USABLEAMOUNTBYFREE CHAR(1) ,
TS CHAR(19) )
on commit preserve rows;

create index i_bd_bd_produce1 on bd_produce (pk_invmandoc,pk_calbody);

create inedx i_tmp_ic_atp_test1 on tmp_ic_atp_test1 (cinventoryid,ctmpcalbodyid);

insert into tmp_ic_atp_test1(ctmpcorpid,ctmpcalbodyid,cinventoryid)
values('1001','1001AA1000000000015U','0001AA1000000000200L')

select count(*) from bd_produre =3178823
size: 476.21M

2.sql的原始执行计划:

分析了table bd_produceindex i_bd_produce1

select bd_produce.pk_corp , bd_produce.pk_calbody ccalbodyid , bd_produce.pk_invmandoc
cinventoryid , bd_produce.safetystocknum nsafenum , bd_produce.usableamount , bd_produce.usableamountbyfree from tmp_ic_atp_test1 ,bd_produce
where tmp_ic_atp_test1.cinventoryid = bd_produce.pk_invmandoc
and tmp_ic_atp_test1.ctmpcalbodyid =bd_produce.pk_calbody

我们发现,在CBO下,该sql执行时间很长。观察该sql的执行计划,发现对table bd_produce进行了全表扫描:

SELECT STATEMENT, GOAL = CHOOSE 8511 1060318
HASH JOIN 8511 1060318
INDEX FAST FULL SCAN IND_TMP_IC_ATP_TEST1 4 719840 NON-UNIQUE
TABLE ACCESS FULL BD_PRODUCE 5755 196450720 -
此处对大表进行了全表扫描

尝试改写sql

select bd_produce.pk_corp , bd_produce.pk_calbody ccalbodyid ,

bd_produce.pk_invmandoc cinventoryid , bd_produce.safetystocknum nsafenum ,

bd_produce.usableamount , bd_produce.usableamountbyfree

from bd_produce

where (pk_invmandoc,pk_calbody)

in (select tmp_ic_atp_test1.cinventoryid,tmp_ic_atp_test1 .ctmpcalbodyid from tmp_ic_atp_test1)

执行计划依然是:TABLE ACCESS FULL BD_PRODUCE

SELECT STATEMENT, GOAL = CHOOSE 8511 1060318

HASH JOIN 8511 1060318

SORT UNIQUE

INDEX FAST FULL SCAN IND_TMP_IC_ATP_TEST1 4 719840 NON-UNIQUE

TABLE ACCESS FULL BD_PRODUCE 5755 196450720

RBO下的情况:

SELECT STATEMENT, GOAL = RULE

TABLE ACCESS BY INDEX ROWID BD_PRODUCE

NESTED LOOPS

TABLE ACCESS FULL TMP_IC_ATP_TEST1

INDEX RANGE SCAN I_BD_PRODUCE1 NON-UNIQUE

table bd_produce进行的是index访问,执行时间很快。

3.分析临时表的统计信息

分析临时表TMP_IC_ATP_TEST1进行统计信息分析后,执行计划终于正常了:

SELECT STATEMENT, GOAL = CHOOSE 4 106

TABLE ACCESS BY INDEX ROWID BD_PRODUCE 3 62

NESTED LOOPS 4 106

INDEX FULL SCAN IND_TMP_IC_ATP_TEST1 44 NON-UNIQUE

INDEX RANGE SCAN I_BD_PRODUCE1 2 NON-UNIQUE

4.改写sql来引导oracle使用index

删除临时表的统计信息,并改写sql

select bd_produce.pk_corp , bd_produce.pk_calbody ccalbodyid ,

bd_produce.pk_invmandoc cinventoryid , bd_produce.safetystocknum nsafenum ,

bd_produce.usableamount,bd_produce.usableamountbyfree from bd_produce ,tmp_ic_atp_test1

where tmp_ic_atp_test1.cinventoryid = bd_produce.pk_invmandoc

and tmp_ic_atp_test1 .ctmpcalbodyid =bd_produce.pk_calbody

and bd_produce.pk_invmandoc > chr(0) –增加一个条件,使oracle使用index

SELECT STATEMENT, GOAL = CHOOSE 1640 53000

TABLE ACCESS BY INDEX ROWID BD_PRODUCE 3 62

NESTED LOOPS 1640 53000

INDEX RANGE SCAN IND_TMP_IC_ATP_TEST1 2 35992 NON-UNIQUE

INDEX RANGE SCAN I_BD_PRODUCE1 2 NON-UNIQUE

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/60217/viewspace-1007878/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/60217/viewspace-1007878/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值