Выполняет ли ResultSet все данные в памяти или только по запросу?

У меня есть страница .jsp, где у меня есть таблица GUI, которая отображает записи из базы данных Oracle. Эта таблица допускает типичное поведение в постраничной форме, такое как "FIRST", "NEXT", "PREVIOUS" и "LAST". Записи получаются из объекта Java ResultSet, который возвращается из выполнения инструкции SQL.

Этот ResultSet может быть очень большой, поэтому мой вопрос:

Если у меня есть ResultSet, содержащий миллион записей, но в моей таблице отображаются только данные из первых десяти записей в ResultSet, данные берутся только при начале запроса данных записи или полностью загружаются все данные в память как только ResultSet возвращается из выполнения инструкции SQL?

Ответ 1

Java ResultSet - это указатель (или курсор) на результаты в базе данных. ResultSet загружает записи в блоки из базы данных. Поэтому, чтобы ответить на ваш вопрос, данные извлекаются только при запросе, но в блоках.

Если вам нужно контролировать, сколько строк извлекается сразу драйвером, вы можете использовать метод setFetchSize() в ResultSet. Это позволит вам контролировать, насколько большие блоки он получает сразу.

Ответ 2

Спецификация JDBC не определяет, передаются ли данные или загружается в память. Потоки Oracle по умолчанию. У MySQL нет. Чтобы заставить MySQL передавать потоковый набор результатов, вам нужно установить в Statement следующее:

    pstmt = conn.prepareStatement(
        sql,
        ResultSet.TYPE_FORWARD_ONLY,
        ResultSet.CONCUR_READ_ONLY);
    pstmt.setFetchSize(Integer.MIN_VALUE);

Ответ 3

Пока спецификация JDBC не указывает, будут ли получены все данные в наборе результатов, любой хорошо написанный драйвер этого не сделает.

Тем не менее, прокручиваемый набор результатов может быть больше того, что вы имеете в виду: (ссылка отредактирована, она указала на страницу-шпион)

Вы также можете рассмотреть набор отключенных строк, который хранится в сеансе (в зависимости от того, насколько масштабируется ваш сайт): http://java.sun.com/j2se/1.4.2/docs/api/javax/sql/RowSet.html

Ответ 4

Лучшая идея - сделать запрос и отображать 100 или 1000 строк за раз/на одной странице. И управление соединением путем объединения пула.

Чтобы сделать дополнительный запрос, вы можете использовать Row count в oracle и Limit в MY SQL.

Ответ 5

позволяет сказать, что у нас есть таблица, содержащая 500 записей в ней

PreparedStatement stm=con.prepareStatement("select * from table");
stm.setFetchSize(100);// now each 100 records are loaded together from the database into the memory,
// and since we have 500 5 server round trips will occur.
ResultSet rs = stm.executeQuery();
rs.setFetchSize (50);//overrides the fetch size provided in the statements,
//and the next trip to the database will fetch the records based on the new fetch size