ResultSet загружает все данные в память или только по запросу?
У меня есть страница.jsp, где у меня есть таблица GUI, которая отображает записи из базы данных Oracle. Эта таблица допускает типичное поведение разбивки на страницы, например "ПЕРВЫЙ", "СЛЕДУЮЩИЙ", "ПРЕДЫДУЩИЙ" и "ПОСЛЕДНИЙ". Записи получены из объекта Java ResultSet, который возвращается при выполнении оператора SQL.
Этот ResultSet может быть очень большим, поэтому мой вопрос:
Если у меня есть ResultSet, содержащий миллион записей, но в моей таблице отображаются только данные из первых десяти записей в ResultSet, данные выбираются только тогда, когда я начинаю запрашивать данные записей, или все данные загружаются в память полностью после ResultSet возвращается из выполнения оператора SQL?
5 ответов
Java ResultSet - это указатель (или курсор) на результаты в базе данных. ResultSet загружает записи в блоках из базы данных. Поэтому, чтобы ответить на ваш вопрос, данные выбираются только тогда, когда вы их запрашиваете, но в блоках.
Если вам нужно контролировать, сколько строк одновременно выбирается драйвером, вы можете использовать метод setFetchSize() в ResultSet. Это позволит вам контролировать размер блоков, которые он получает одновременно.
В спецификации JDBC не указывается, передаются ли данные в потоковом режиме или загружаются в память. Oracle потоков по умолчанию. MySQL нет. Чтобы заставить MySQL передавать поток результатов, вам нужно установить следующее в операторе:
pstmt = conn.prepareStatement(
sql,
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY);
pstmt.setFetchSize(Integer.MIN_VALUE);
Лучше всего сделать подзапрос и отобразить 100 или 1000 строк за раз / на одной странице. И управление соединением с помощью пула соединений.
Чтобы сделать подзапрос, вы можете использовать количество строк в Oracle и Limit в MY SQL.
Хотя в спецификации JDBC не указано, будут ли извлечены все данные в наборе результатов, любой хорошо написанный драйвер этого не сделает.
Тем не менее, прокручиваемый набор результатов может быть больше, чем вы думаете: (ссылка отредактирована, она указывает на страницу шпионского ПО)
Вы также можете рассмотреть отключенный набор строк, который хранится в сеансе (в зависимости от того, насколько масштабируемым должен быть ваш сайт): http://java.sun.com/j2se/1.4.2/docs/api/javax/sql/RowSet.html
Допустим, у нас есть таблица, которая содержит 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