SQL优化案例-自定义函数索引(五)
SQL文本如下,表本身很小,走全表扫描也很快,但因业务重要性,要求尽可能缩短查询时间(为保证客户隐私,已经将注释和文字部分去掉):
SELECTMERCHCODEASR_MERCHCODE,TRANDATE,TRANTIME,TRANTYPEASTRANSTYPE,TRACENO,POSIDASR_POSID,ACCOUNTASR_CARDNO,AMT,FEE,NVL(RESERVED1,'N')BORDERCARDBUSIFLAG,CASEWHENI.BANCSRETFLAG='0000'THEN'1'WHENI.BANCSRETFLAG='9999'THEN'0'ELSE'2'ENDASRETURNCODEFROMIC_MERCHTRANSDETAIL_428IWHEREGETACCTNO(ACTSTLACCTNO)=GETACCTNO('14250000000454865')ANDROWNUM<500;
执行计划如下:
可以看到谓词信息是客户号,可以确定此列选择性非常高,非常适合建立索引。
CREATEINDEXIDX_GETACCTNOONIC_MERCHTRANSDETAIL_428(GETACCTNO(ACTSTLACCTNO))PARALLEL10TABLESPACEREPT*ERRORatline1:ORA-30553:Thefunctionisnotdeterministic
确定函数本身不会受到不确定值的影响,创建函数索引。
加上deterministic并且取别名,查看函数创建语句:
CREATEORREPLACEFUNCTIONGETACCTNOCY(acctvarchar2)returnvarchar2DETERMINISTICistmpacctvarchar2(40);st_resvarchar2(40);--st_res:=tmpacctbegintmpacct:='';st_res:='';IF(length(trim(acct))=16)THENBEGINSELECTACCOUNTINTOtmpacctFROMLINK_LWHERELINK_L.CARD=LPAD(trim(acct),20,0)ANDISO_TYPE='1'ANDCATEGORY='0';EXCEPTIONWHENNO_DATA_FOUNDTHENtmpacct:=TRIM(ACCT);END;ENDIF;IF(length(trim(acct))>17)THENBEGINSELECTzhINTOtmpacctFROMload_zhmapWHEREjzh=trim(acct);EXCEPTIONWHENNO_DATA_FOUNDTHENtmpacct:='';END;ENDIF;IF(length(trim(acct))=17)THENtmpacct:=substr(acct,1,16);ENDIF;st_res:=tmpacct;returnst_res;EXCEPTIONWHENOTHERSTHENreturn'';END;
创建索引:
CREATEINDEXIDX_GETACCTNOONIC_MERCHTRANSDETAIL_428(GETACCTNOCY(ACTSTLACCTNO))TABLESPACETBSIDX;
创建索引后的执行计划如下:
案例较为简单,希望可以帮助到大家。
| 作者简介
姚崇·沃趣科技高级数据库技术专家熟悉Oracle数据库内部机制,丰富的数据库及RAC集群层故障诊断、性能调优、OWI、数据库备份恢复及迁移经验。声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。