我有CallableStatement,我用它来使用存储过程从DB中检索大约500条记录。
我平均返回结果300毫秒,但处理所有这些记录大约需要1-2秒。
CallableStatement a = connection.prepareCall("SP_HERE",ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
a.setFetchSize(4000);
比:(我收到的回复很少)
boolean hadResults = a.execute();
while (hadResults) {
ResultSet rs = a.getResultSet();
List<Map<String,DBInput>> tmpDB = processResultSet(rs);
...
hadResults = a.getMoreResults();
}
滞后部分在这里:
private List<Map<String,DBInput>> processResultSet (ResultSet rs){
List<Map<String,DBInput>> dbIn = new ArrayList<>();
try {
while (rs.next()){
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
Map<String,DBInput> map = new HashMap<>();
for (int i = 1; i <= columnCount; i++) {
String columnName = rsmd.getColumnLabel(i);
DBInput tmp = new DBInput();
int columnType = rsmd.getColumnType(i);
Object value = null;
int type = OEMIO.NULL;
long timeBefore = System.currentTimeMillis();
switch (columnType){
case VARCHAR:
value = rs.getString(i);
type = OEMIO.STRING;
break;
case CHAR:
value = rs.getString(i);
type = OEMIO.STRING;
break;
case INTEGER:
value = rs.getInt(i);
type = OEMIO.INTEGER;
break;
case DECIMAL:
value = rs.getBigDecimal(i);
if (value != null) value = ((BigDecimal)value).doubleValue();
type = OEMIO.DOUBLE;
break;
case TIMESTAMP:
if (rs.getTimestamp(i) == null) break;
value = rs.getTimestamp(i).toString();
if(rs.getTimestamp(i).toString().contains(" ")){
value = rs.getTimestamp(i).toString().replace(" ", "T") + "Z";
}
type = OEMIO.DATE;
break;
case DATE:
if (rs.getDate(i) == null) break;
value = rs.getDate(i).toString();
if(rs.getDate(i).toString().contains(" ")){
value = rs.getDate(i).toString().replace(" ", "T") + "Z";
}
type = OEMIO.DATE;
break;
case BIT:
value = rs.getBoolean(i);
type = OEMIO.BOOLEAN;
break;
default:
value = "NO TYPE IDENTIFIED";
type=-1;
}
long timeAfter = System.currentTimeMillis();
long diff = timeAfter-timeBefore;
if (diff > 10) {
logger.debug("Column: " + diff + "ms" + " " + columnType + " index id: " + i);
OrdersManagerThread.type.add(columnType+"");
}
tmp.setDbInput(columnName);
tmp.setType(type);
tmp.setValue(value);
map.put(columnName, tmp);
}
dbIn.add(map);
}
} catch (SQLException e) {
logger.error("Error parsing ResultSet: " + e.getMessage());
}finally{
rs.close();
}
return dbIn;
}
出于某些原因,我不明白为什么有时候,从RecordSet获取结果时,switch case是否会滞后? 这是测试版:
列:170ms 12索引id:34
列:165ms 12索引id:50
列:142ms 12索引id:55
列:171ms 12索引id:4
列:180ms 12索引id:76
列:151ms 12索引ID:68
列:80ms 12索引id:62
列:90ms 3索引id:16
列:79ms 12索引id:9
列:89ms 12索引id:4
列:85ms 3索引id:15
列:85ms 1索引id:10
列:101ms 12索引id:4
什么可能导致这些滞后?
由于
更新:
添加
**Thread.sleep (10000);**
boolean hadResults = a.execute();
while (hadResults) {
ResultSet rs = a.getResultSet();
List<Map<String,DBInput>> tmpDB = processResultSet(rs);
...
hadResults = a.getMoreResults();
}
&#34;修正&#34;问题。什么可能导致这种情况发生?或者它是否给出任何解决方向?
答案 0 :(得分:0)
您的抓取尺寸看起来很小。这可能会导致额外的往返服务器。尝试增加它。如果可以的话,我会从大到足以容纳整个结果集的东西开始,然后退回以找到内存和I / O之间的快乐平衡