萬惡的隱式數據類型轉換

2年前上線的系統了,運行兩年了啊(意思是忍受了這麼慢的查詢很久了)!!!
——正式開始之前,先吐吐槽。。。。。

場景描述:系統中查詢條件涉及日期的所有操作,都會導致數據庫IO開銷突增。
-------------------------------------------------------------------------
解決過程:
0.檢查日期字段,看其上有無索引,這個是有的
1.拉下來項目代碼,配置jrebel,配置log4j,啓動項目
2.登錄系統,查詢,拉取控制檯SQL,手動補齊參數值,執行,看執行計劃。速度快開銷小,木發現有大問題…… 納悶。。。。。不解。。。。。
3.設置log4j,重啓項目,重新執行2:
1)修改
log4j.rootLogger=INFO, stdout
2)新增
log4j.logger.org.hibernate.type=TRACE
log4j.logger.org.hibernate.sql=TRACE
4.查看對日期字段綁定的日期值的類型,竟然是TimeStampType!!!腫麼會這樣???傳進去的值明明是Date類型的。。。。。這樣查詢不會走索引,而且要把日期列的每個值都轉換成時間戳類型再跟傳入的值比較。。。。。介個隱式數據類型轉換也太神奇了吧
5.將所有類似
hql.append(" and table_name.d_column_name = :d_column_name");
的語句改爲
hql.append(" and table_name.d_column_name = cast(:d_column_name as date)");
這樣雖然我Trace到的還是TimeStampType,但是在查詢裏轉換成Oracle DATE類型了,就可以走索引了。
問題解決。
-------------------------------------------------------------------------
疑惑:
1.出現這種問題原因是什麼?肯定不是日期格式的問題,因爲要在頁面上設定日期範圍的查詢,雖然傳入字符串並轉爲短日期格式傳入,最後Trace到的還是時間戳類型。不明白,hibernate明明是有DateType的啊。
2.有沒有方法可以通過配置hibernate一次性解決這種日期類型轉換爲時間戳類型的問題?
以上兩個疑惑,苦逼DBA問過開發,他們也不知道……

後記:EM中也可以排查到這個問題:Advisor Central>Advisors>Advisor Tasks>Advisory Type = SQL Tuning Advisor > Go > View Result > Overall Task Statistics > Restructure SQL > Select one line> View Recommendations
[b]Type[/b]
Restructure SQL
[b]Findings[/b]
The predicate "table_name"."d_column_name"=:B1 used at line ID 6 of the execution plan contains an implicit data type conversion on indexed column "d_column_name". This implicit data type conversion prevents the optimizer from selecting indices on table "user_name"."table_name".
[b]Recommendations[/b]
Rewrite the predicate into an equivalent form to take advantage of indices.
[b]Rationale[/b]
The optimizer is unable to use an index if the predicate is an inequality condition or if there is an expression or an implicit data type conversion on the indexed column.
很明白對吧,謂詞"table_name"."d_column_name"=:B1 包含對已加索引的日期列d_column_name上的隱式數據類型轉換,導致無法使用索引,於是乎,數據量大了之後,杯具就發生了。。。。。

P.S.(真囉嗦啊)之前的項目用SQL Server數據庫,並無此問題。原因是'2012-02-01 00:00:00'這種日期格式,SQL Server可以直接識別,如果日期列上加了索引,則可走索引。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章