記一次Mybatis+Oracle, 資料多且日期間隔大時, 查詢非常慢解決過程
阿新 • • 發佈:2019-02-18
前兩天發現一個sql在專案執行時查詢時間的很長, 但sql在PLSql中查詢時只要1s左右, 以下是原sql:
百度後發現有網友說是preparedstatement的問題, 遂把#換成了$, 並用了to_date函式, 如下:SELECT MAX(data) DATA_VALUE FROM ( SELECT A.FREEZE_TIME, SUM(A.AP * T2.add_attr * T2.pct / 100) data FROM T_CUR_AP A INNER JOIN (SELECT lm.METER_ID, lm.add_attr, lm.pct FROM T_LEDGER_METER lm WHERE lm.LEDGER_ID =#{baseId}) T2 ON A.METER_ID = T2.METER_ID WHERE A.FREEZE_TIME >= #{beginTime,jdbcType=TIME} AND A.FREEZE_TIME <= #{endTime,jdbcType=TIME} GROUP BY A.FREEZE_TIME)
SELECT MAX(data) DATA_VALUE FROM ( SELECT A.FREEZE_TIME, SUM(A.AP * T2.add_attr * T2.pct / 100) data FROM T_CUR_AP A INNER JOIN (SELECT lm.METER_ID, lm.add_attr, lm.pct FROM T_LEDGER_METER lm WHERE lm.LEDGER_ID =#{baseId}) T2 ON A.METER_ID = T2.METER_ID WHERE A.FREEZE_TIME >= to_date('${beginTime}', 'yyyy-mm-dd hh24:mi:ss') AND A.FREEZE_TIME <= to_date('${endTime}', 'yyyy-mm-dd hh24:mi:ss') GROUP BY A.FREEZE_TIME)
這樣確實可以, 但是專案中為了防止sql注入, 不允許使用$, 故繼續查閱資料(還不是百度-.-!!)
然後在這篇部落格(http://www.mamicode.com/info-detail-1892493.html)中發現可能是jdbcType的問題, 故查看了下我們表中的日期型別為Date, 於是找到oracle的欄位型別:
發現Date對應的java資料型別是Timestamp, 而我們程式碼中用的型別是Time, 故將程式碼中的jdbcType換為Timestamp, 如下
SELECT MAX(data) DATA_VALUE FROM ( SELECT A.FREEZE_TIME, SUM(A.AP * T2.add_attr * T2.pct / 100) data FROM T_CUR_AP A INNER JOIN (SELECT lm.METER_ID, lm.add_attr, lm.pct FROM T_LEDGER_METER lm WHERE lm.LEDGER_ID =#{baseId}) T2 ON A.METER_ID = T2.METER_ID WHERE A.FREEZE_TIME >= #{beginTime,jdbcType=TIMESTAMP} AND A.FREEZE_TIME <= #{endTime,jdbcType=TIMESTAMP} GROUP BY A.FREEZE_TIME)
問題解決!