小坑記-java.util.Date 做爲查詢條件致使Oracle數據庫Date類型的字段索引失效

同事在配置報表時,有一張報表查詢老是超時,而該段sql放到pl/sql中執行徹底沒問題,秒出級別的,好吧,本身不知道哪裏挖的坑,仍是須要本身填的。後來思考了集中可能出現的問題,一一排查:java

select A_COLUMN,B_COLUMN,C_COLUMN,TIME_STAMP from TABLEA where TIME_STAMP in (?)sql

1.強制指定該字段的索引執行,將報表查詢sql改成:app

       select A_COLUMN,B_COLUMN,C_COLUMN,
       /*+index(A IDX_DFRS_INTERFACE_5M_001)*/
       TIME_STAMP from TABLEA A where   TIME_STAMP in (?)ide

           執行仍超時!學習

2.將條件寫死執行:測試

select A_COLUMN,B_COLUMN,C_COLUMN,TIME_STAMP from TABLEA where TIME_STAMP in (to_date('201705171500','yyyyMMddhh24mi'))this

           執行成功!繼承

走到這裏能夠基本推想是Java自動注入後致使索引失效。可是爲何會失效?用其餘幾千條的表測試是OK的,這個表有3億+ 近4億的數據量就不行了。索引

後來查看代碼發現 Date條件是new java.util.Date();那我換成new java.sql.Date()        試了一下,OK了~再換成new java.sql.Time() 也是OK的,那就是這個緣由了!源碼

以前只是知道兩個Date的應用場景不同,可是不知道具體會有什麼差別,這個小bug讓我也學習到了。至於說具體的差異在哪裏,翻看源碼發現瞭如下幾點:

a). java.sql.Date 繼承了 java.util.Date

b). java.sql.Date 註釋中描述了這個子類:

A thin wrapper around a millisecond value that allows JDBC to identify this as an SQL DATE  value.

一個容許JDBC去將這個類識別爲一個SQL DATE 的關於毫秒值的簡單封裝。

-------補充-------

既然類自己沒有什麼特別的地方,那必定是其餘地方做了區分,而後看了Oracle驅動包發現,裏面會對每種類型進行區分,而對時間的處理正是識別爲java.sql.Date|Time.

相關文章
相關標籤/搜索