oracle執行計劃------未走索引,隱式轉換的坑

e71hao發表於2021-03-21

一、問題

業務方一條sql語句很奇怪,執行時間0.4秒,資料量不大,兩張表,每張表40萬條資料,左連線,都有索引,where條件欄位有索引。

看上面執行計劃,是不是很完美。查詢出來一條資料,謂詞條件AGGREGATE_ORDER_NO = :1   也很完美,可以定位出來一條語句。

二、分析

      這個語句說簡單其實很簡單,2個表,左連線,每個表資料量40多萬。執行計劃也顯示出完美情況來。但是在awr報表中這個語句平均執行時間0.4秒,按理來說,應該是0.01秒,或者0.00秒,忽略不計的呀。難道我這個執行計劃有問題?不是真實的執行計劃?

三、檢驗是否是真實執行計劃

 

看真實的執行計劃,就用如下語句:

 ALTER SESSION SET STATISTICS_LEVEL=ALL;

 execute sql 

 select * from table(dbms_xplan.display_cursor(null,null,'allstats last'));

用如上方法可以檢視執行計劃,因為使用了繫結變數,所以我設定一下

var  vno varchar2(80)

exec :vno :='sjdkfjlks'


select a.PAY_TYPE, a.STORE_ID, a.AGGREGATE_ORDER_NO, a.TOTAL_PAYABLE_AMOUNT, a.ACTUAL_PAY_AMOUNT, a.CURRENCY, a.REMARK, a.AGGREGATE_ORDER_STATE, a.BUSINESS_ORDER_STATE, a.CREATE_TIME, a.BUSINESS_LINE, a.COMMENT_ORDER_STATE, a.REFUND_ORDER_STATE, a.SHOW_URL as SHOP_LOGO, a.STORE_NAME, a.BUSINESS_CONTENT, p.OUT_PAY_ORDER_NO, p.PAY_STATE from xxx_ORDER a left join xxx_order p on(a.pay_order_no = p.pay_order_no) where a.DEL_STATE = 10 and a.AGGREGATE_ORDER_NO = to_char(:vno) order by a.id desc 

結果發現還是沒有問題

四、分析到這裡好像進入了死衚衕,執行計劃沒有問題,索引也有,但是執行時間就是下不來,而且還提示這個語句佔用cpu巨多。思索了好幾天,困擾了我好幾天。後來靈機一閃,是不是應該把awr的執行計劃調出來呢?

用如下語句呼叫awr執行計劃

select * from table(dbms_xplan.display_awr('3ypyandfvscts',null,null,'all'));

仔細看上面執行計劃,發現了沒有,居然沒有走索引掃描,而是走了全表掃描。不是有索引嗎?百思不得姐

五、看上面的分析,好像又陷入了死衚衕,百思不得姐。為啥明明有索引,卻不走索引呢?百度了一下,不走索引有哪些情況呢?

比較不匹配型別的資料型別

等於和範圍索引不會被合併使用

WHERE子句中使用不等於條件

使用前導模糊查詢

WHERE子句中使用函式

後來經過我和開發仔細對照,發現傳給繫結變數的是數字,而不是字串。所以,我做了如下實驗發現,果然,如果是數字,會導致不走索引。

看到上面關鍵語句r((TO_NUMBER("A"."AGGREGATE_ORDER_NO")=:VNO,導致全表掃描。

六、結論出來了,改變也容易了。開發寫錯誤,把是字串型別寫成數字型別。糾正過來就可以了,執行時間是0.00秒,問題解決。困擾我幾天的問題解決了。百思不得姐

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30393770/viewspace-2764049/,如需轉載,請註明出處,否則將追究法律責任。

相關文章