(轉) JAVA,Mybatis,Oracle變數型別與欄位型別不一致,分割槽表全掃的優化

gdutllf2006發表於2017-12-12
http://blog.itpub.net/28602568/viewspace-2134772/

開發反應[增量庫存]功能慢,並反饋查詢
有指定分割槽條件,量較小;

1)通過 Oracle DBA常用sql分享 (正在執行的sql) 發現,該SQL的COST>1400000;
2)再通過select * from table(dbms_xplan.display_cursor( 'SQL_ID','0','advanced'));  分析該sql的執行計劃和繫結變數情況發現
  
             PARTITION RANGE ALL 分割槽全掃;---->createtm分割槽欄位傳引數了 為啥會全掃?
                                               |
                            繫結變數中createtm分割槽條件顯示有傳值 
                                               |
 分割槽條件createtm 部分有【INTERNAL_FUNCTION 隱含轉換函式】;---> 猜測 傳參型別和DB欄位型別不一致導致分割槽表全掃;
                                               |
通過DBA_HIST_SQLBIND查到createtm分割槽條件傳參(2017/01/17 14:20:00 -2017/01/17 14:25:00),欄位型別為timestamp,而createtm欄位為date型別;
 
總結:
   開發在java層用的mybatis框架,把date型別欄位轉換成timestamp型別【and createtm $gt:=#{params.begintm} and createtm $lt:#{params.endtm}】,出現INTERNAL_FUNCTION 隱含轉換,導致及時分割槽條件createtm傳分割槽條件也被識別成未傳變數,導致分割槽表全掃;
   優化後 and createtm>= to_date(#{params.begintm},'yyyy-mm-dd hh24:mi:ss')  and createtm< to_date(#{params.endtm},'yyyy-mm-dd hh24:mi:ss')
    
--補充注意Java中的日期變數需要使用String來儲存.



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

相關文章