Обработка запроса MySQL занимает слишком много времени и выдает «Ошибка канала связи» - PullRequest
4 голосов
/ 30 марта 2012

Я отправил запрос с использованием соединения JDBC:

Connection conn = null
Class.forName("com.mysql.jdbc.Driver")
conn = DriverManager.getConnection(dbHost, dbUser, dbPass)

s = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
s.setFetchSize(Integer.MIN_VALUE);
r = s.executeQuery (MY_SELECT_QUERY);
while(...) { 
  processResultSet(r);
}

while долго работает с ResultSet.Примерно через 1 час я получил исключение:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: сбой линии связи

Последний пакет, успешно полученный от сервера, составил 74 миллисекунды.тому назад.Последний пакет, успешно отправленный на сервер, был 4 351 980 миллисекунд назад.

   at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
   at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)

   at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)

   at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
   at com.mysql.jdbc.Util.handleNewInstance(Util.java:407) 
   at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116)

   at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3082) 
   at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2968) 
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3516) 
   at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:931) 
   at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1429) 
   at com.mysql.jdbc.RowDataDynamic.nextRecord(RowDataDynamic.java:416) 
   at com.mysql.jdbc.RowDataDynamic.next(RowDataDynamic.java:395) 
   at com.mysql.jdbc.ResultSetImpl.next(ResultSetImpl.java:7171) 
   at com.busk.indexer.AbstractIndexerClient.indexResultSet(AbstractIndexerClient.scala:34)

   at com.busk.indexer.ContinousIndexer.startIndexingLoop(ContinousIndexer.scala:18)

   at com.busk.indexer.IndexerServer$.main(IndexerServer.scala:95) 
   at com.busk.indexer.IndexerServer.main(IndexerServer.scala) 
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)

   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

   at java.lang.reflect.Method.invoke(Method.java:597)

Я погуглил, но почти все ошибки связаны с пулом соединений и использованием соединения более 8 часов (настройка по умолчанию wait_timeout mysql).В моем случае я нахожусь в процессе обработки ResultSet и получаю эту ошибку.

1 Ответ

1 голос
/ 31 марта 2012

Если это происходит из-за большого количества данных в наборе результатов, я бы предложил разбить ответ на страницы с помощью «LIMIT s, m» (где s - начало и m - макс. Записи - оба целых числа).Затем обработайте эти данные в цикле с порциями по 1000 записей за раз:

boolean finished = false;
int start = 1;
int max = 1000;
do {
   r = s.executeQuery (MY_SELECT_QUERY + " LIMIT " + start + ", " + max);
   finished = // if r returned less than M records
   while(...) { 
     processResultSet(r);
   } 
   start += // number of returned records;
} while (!finished);

Конечно, 1000 - это произвольное число, вы можете поиграть и найти оптимальный максимальный размер для вашего запроса.

ОБНОВЛЕНИЕ: Если обработка каждой записи занимает много времени, сохраняйте записи в списке и просматривайте их, когда все данные извлекаются из базы данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...