У меня есть CallableStatement, который я использую для получения около 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? вот тестовые отпечатки:
Столбец: 170 мс 12 идентификатор индекса: 34
Столбец: 165 мс 12 идентификатор индекса: 50
Столбец: 142 мс 12 идентификатор индекса: 55
Столбец: 171 мс 12 идентификатор индекса: 4
Столбец: 180 мс 12 идентификатор индекса: 76
Столбец: 151 мс 12 идентификатор индекса: 68
Столбец: 80 мс 12 идентификатор индекса: 62
Столбец: 90 мс 3 идентификатор индекса: 16
Столбец: 79 мс 12 идентификатор индекса: 9
Столбец: 89 мс 12 идентификатор индекса: 4
Столбец: 85 мс 3 идентификатор индекса: 15
Столбец: 85 мс 1 идентификатор индекса: 10
Столбец: 101 мс 12 идентификатор индекса: 4
Что может вызвать эти задержки?
Спасибо
ОБНОВИТЬ:
добавление
**Thread.sleep (10000);**
boolean hadResults = a.execute();
while (hadResults) {
ResultSet rs = a.getResultSet();
List<Map<String,DBInput>> tmpDB = processResultSet(rs);
...
hadResults = a.getMoreResults();
}
"Решить проблему. что могло вызвать это? или это дает направление для исправления?




ваш размер выборки выглядит маленьким. Это может вызвать дополнительные обращения к серверу. Попробуйте увеличить его. Я бы начал с чего-то достаточно большого, чтобы вместить весь набор результатов, если вы можете, затем отступил, чтобы найти удачный баланс между памятью и вводом-выводом.
Посмотрите на мое обновление, я увеличил размер выборки, но результат не изменился. только ожидание перед обработкой ResultSet по какой-то причине изменило результат.