程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> Oracle版本驅動中使用Java Date產生問題的解答

Oracle版本驅動中使用Java Date產生問題的解答

編輯:Oracle數據庫基礎

如果你在Oracle版本驅動中使用Java Date時產生一些問題的時候,你是否想了解不解之處,以下的文章主要是通過對Oracle版本驅動中使用Java Date的問題的實際應用的方案的介紹,來解答你在Oracle版本驅動中使用Java Date的問題在實際操作方面的問題。

這裡兩天都在對一條sql進行調優。該sql並不復雜,類似於

  1. select ... from some_vIEw union all select ... 
    from some_table where datetime >= d1 and datetime< d2 and ....  

底層使用

  1. ibatis2.1.6 + Oracle 10g 

今天花了些時間繼續研究這個問題,導致該問題的原因的確是“導致oracle對datetime字段進行了隱式類型轉換,最終CBO未能使用該列的全局索 引”,不過問題不是出在ibatis上而是Oracle driver。設我們使用這樣的sql通過綁定變量(類型為Java.util.date)查詢數據庫,其中end_date是date類型且建立了索引。

  1. “select count(*) from table1 where end_date >=
     :1 and end_date <= :2” 

通常,面對這樣的sql,我們希望它的執行計劃走index range scan。然而在默認情況下oracle CBO是不會選擇走索引地,以上面這語句為例,oracle實際走的是table full scan。為什麼會這樣 呢?這類問題是Oracle版本在9.2以後引入了TIMESTAMP才開始出現的。

在 9.2之前,Oracle只有DATE,而沒有TIMESTAMP。在jdbc preparedStatement.setTimestamp時,綁定變量的類型會被正確的設置為DATE。而在9.2之後,Oracle開始支持 TIMESTAMP了,這兩者都能支持精度為yyyy-MM-dd hh24:mi:ss的時間(當然TIMESTAMP能支持到納秒級別)。

但jdbc driver的api未變同樣在preparedStatement.setTimestamp時,oracle driver就得選擇到底該把綁定變量的類型設置為DATE還是TIMESTAMP呢?估計是由於TIMESTAMP的精度更高,Oracle 最終默認選擇了將綁定變量的類型設置為了TIMESTAMP。那麼這個時候,如果面對實際屬性為DATE的列,那麼就會導致 Oracle隱式地進行形如

  1. “TO_TIMESTAMP(date_column) = parameter_timestamp” 

轉換,要 知道Oracle CBO不會選擇被某函數作用的列上的索引,除非是函數索引。因此,最終也會導致最上面的情況使用table full scan而不是index range scan。

Oracle版本就沒有提供別的方法來正確地提供綁定變量嗎?Oracle提供 了幾個方法來解決這個問題

1.升級到11g並使用新的正確的driver api。

2.將DATE列全都改成 TIMESTAMP列。

3.使用V8Compatible flag。

以上就是對Oracle版本驅動中如何使用Java Date的相關的內容的介紹,望你會有所收獲。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved