记一次Mybatis+Oracle, 数据多且日期间隔大时, 查询非常慢解决过程

前两天发现一个sql在项目运行时查询时间的很长, 但sql在PLSql中查询时只要1s左右, 以下是原sql:

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)
百度后发现有网友说是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 >= 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的字段类型:记一次Mybatis+Oracle, 数据多且日期间隔大时, 查询非常慢解决过程_第1张图片

发现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)

问题解决!

你可能感兴趣的:(记一次Mybatis+Oracle, 数据多且日期间隔大时, 查询非常慢解决过程)