CachedRowSet медленнее, чем ResultSet? - PullRequest
3 голосов
/ 06 октября 2011

В моем Java-коде я получаю доступ к таблице базы данных оракула с помощью оператора select.Я получаю много строк (около 50 000 строк), поэтому rs.next() требуется некоторое время для обработки всех строк.

using ResultSet, the processing of all rows (rs.next) takes about 30 secs

Моя цель - ускорить этот процесс, поэтому я изменил коди теперь, используя CachedRowSet:

using CachedRowSet, the processing of all rows takes about 35 secs

Я не понимаю, почему CachedRowSet медленнее, чем обычный ResultSet, потому что CachedRowSet извлекает все данные одновременно, а ResultSet извлекает данные каждый раз, когда вызывается rs.next.

Вот часть кода:

try {
    stmt = masterCon.prepareStatement(sql);
    rs = stmt.executeQuery();

    CachedRowSet crset = new CachedRowSetImpl();
    crset.populate(rs);

    while (rs.next()) {
        int countStar = iterRs.getInt("COUNT");
        ...
    }
} finally {
    //cleanup
}

Ответы [ 4 ]

4 голосов
/ 03 августа 2012

Существует проблема с CachedRowSet в сочетании с драйвером jdbc postgres.

CachedRowSet необходимо знать типы столбцов, чтобы он знал, какие объекты Java следует создать (бог знает, что еще этоизвлекает из БД из-за обложек!).

Таким образом, он делает больше обращений к БД для извлечения метаданных столбца.В очень больших объемах это становится реальной проблемой.Если БД находится на удаленном сервере, это также является реальной проблемой из-за задержки в сети.

Мы использовали CachedRowSet в течение многих лет и только что обнаружили это.Теперь мы внедрили наш собственный CachedRowSet, так как мы никогда не использовали какой-либо из этих причудливых вещей.Мы делаем getString для всех типов и конвертируем себя, поскольку это кажется самым быстрым способом.

Это явно не было проблемой с размером выборки, так как драйвер postgres выбирает все по умолчанию.

4 голосов
/ 06 октября 2011

CachedRowSet кэширует результаты в памяти, то есть вам больше не нужно соединение. Поэтому он "медленнее", в первую очередь.

Объект CachedRowSet - это контейнер для строк данных, который кэширует его строк в памяти, что позволяет работать без будучи подключенным к его источнику данных.

-> http://download.oracle.com/javase/1,5.0/docs/api/javax/sql/rowset/CachedRowSet.html

3 голосов
/ 06 октября 2011

Что заставляет вас думать, что ResultSet будет извлекать данные каждый раз, когда вызывается rs.next()? Это зависит от реализации, как именно она работает - и я не удивлюсь, если она получит порцию за раз; вполне возможно, довольно большой кусок.

Я подозреваю, что вы в основном видите, сколько времени требуется, чтобы скопировать все данные в CachedRowSet и , а затем получить доступ ко всем - в основном у вас есть дополнительная операция копирования без цели.

0 голосов
/ 11 августа 2016

Используя обычный ResultSet, вы можете получить больше опций оптимизации с помощью RowPrefetch и FetchSize.

Они оптимизируют фрагменты сетевого транспорта и обработку в цикле while, поэтому у rs.next () всегда есть данные для работы.

FetchSize имеет значение по умолчанию 10 (последние версии Oracle), но, как я знаю, RowPrefetch не установлен. Таким образом, сетевой транспорт вообще не оптимизирован.

...