Oracle SQL执行计划异常的处理方法
这篇文章主要介绍“Oracle SQL执行计划异常的处理方法”,在日常操作中,相信很多人在Oracle SQL执行计划异常的处理方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Oracle SQL执行计划异常的处理方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
现象:
下面语句一直以来都比较高效,执行计划用了索引范围扫描后经历三次嵌套循环,可在2秒内返回结果,但今天经同事反映却走了1分多钟!
原SQL语句:
Select*From(SelectRownumAsRownumber__,t.*From(SelectT1.OrderdateAs"OrderDate",T1.StatusAs"Status",T1.OrdercodeAs"OrderCode",T1.SumamtAs"SumAmt",T1.OrdertypeAs"OrderType",T1.QuestiondescAs"QuestionDesc",T1.OrdersourceAs"OrderSource",T2.AccepterAs"Accepter",T2.CityAs"City",T1.IsquestionAs"IsQuestion",T1.IssplitAs"IsSplit",T1.SalemodeAs"SaleMode",T1.StockoutAs"StockOut",T2.EncmobileAs"EncMobile",T2.EncphoneAs"EncPhone",Decryptbykey(T2.Mobilephone)As"MobilePhone",T2.ProvinceAs"Province",T3.CheckercodeAs"CheckerCode",T3.IscancelAs"IsCancel",T3.IscheckAs"IsCheck",T3.IscloseAs"IsClose",T3.IsfinishAs"IsFinish",T1.IschangeAs"IsChange"FromXs_OrderT1JoinXs_OrderpsaddressT2OnT1.Ordercode=T2.OrdercodeJoinXs_OrderstatusT3OnT1.Ordercode=T3.OrdercodeOrderByT1.OrdercodeDesc)tWhere"OrderDate">=:Orderdate0And"StockOut"=:Stockout1)TempWhereRownumber__>0andRownumber__<=20
后来查看执行计划,执行计划变成:
分析:
由于后面两个表是大表,全表扫描导致大量的IO消耗,该语句采用了绑定变量,如果把绑定变量调整为常量后,执行计划正常走了索引连接,执行后返回也是在2秒内。曾经以为是绑定变量窥探异常问题,后来把表的统计信息重新更新后,问题依旧,接着运行SQL TUNNING包,概要只建议说要启用并行,但全表扫描并没有消除,考虑到代价太高就放弃,于是想用DBMS_SPM包来载入该语句:
BASELINE:declarel_plsnumber;beginl_pls:=DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE(sql_id=>'a0wawpy5hfrt3',plan_hash_value=>2253704843,--注意这里的2253704843是我用常量带入后正常的PLAN_HASH_VALUEenabled=>'YES');end;
执行后,发现语句还是走了错误的执行计划,曾经考虑想用捕捉基线的方式进行演化,但由于该语句带绑定变量,会话级比较难搞,所以想到用包删除共享池里的该执行计划,让它重新进行硬解析:操作如下:
execdbms_shared_pool.purge('0000000DE5E6B808,2332516131','c')
–第一个参数为v$sqlarea中address和hash_value,第二个为cursor类型)
处理后执行计划重新产生,并自动应用了2253704843这个执行计划,查询效率正常:
到此,关于“Oracle SQL执行计划异常的处理方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。