前两天发现一个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的字段类型:
发现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)
问题解决!