Какой самый быстрый способ получения последовательных данных из базы данных? - PullRequest
0 голосов
/ 19 июля 2011

У меня много строк в базе данных, и она должна быть обработана, но я не могу извлечь все данные в память из-за ограничений памяти.

В данный момент я использую LIMIT и OFFSETчтобы получить данные для получения данных в некотором заданном интервале.

Я хочу знать, является ли это более быстрым способом или есть другой способ получения всех данных из таблицы в базе данных.Фильтр не будет применен, все строки будут обработаны.

Ответы [ 2 ]

5 голосов
/ 19 июля 2011
SELECT * FROM table ORDER BY column

Нет причин загружать всю таблицу в оперативную память. Просто откройте курсор и начните читать. Вы можете играть в игры с размером выборки, а что нет, но БД с удовольствием сохранит свое место, пока вы обрабатываете свои строки.

Addenda:

Хорошо, если вы используете Java, у меня есть хорошая идея, в чем ваша проблема.

Во-первых, просто используя Java, вы используете курсор. Это в основном то, что ResultSet в Java. Некоторые ResultSet более гибкие, чем другие, но 99% из них простые, перенаправляйте только ResultSets, которые вы вызываете «next» для получения каждой строки.

Теперь о вашей проблеме.

Проблема, в частности, связана с драйвером Postgres JDBC. Я не знаю, почему они это делают, возможно, это спецификация, возможно, это что-то еще, но независимо от того, у Postgres есть любопытная особенность, что, если в вашем Connection для autoCommit установлено значение true, то Postgres решает засосать весь набор результатов либо выполнить метод или первый следующий метод. Не очень важно, где, только если у вас есть несколько строк строк, вы получите хорошее исключение OOM. Не полезно.

Это легко может быть именно тем, что вы видите, и я ценю, что это может быть довольно расстраивающим и сбивающим с толку.

Большинство соединений по умолчанию имеет значение autoCommit = true. Вместо этого просто установите autoCommit на false.

Connection con = ...get Connection...
con.setAutoCommit(false);
PreparedStatement ps = con.prepareStatement("SELECT * FROM table ORDER BY columm");
ResultSet rs = ps.executeQuery();
while(rs.next()) {
    String col1 = rs.getString(1);
    ...and away you go here...
}
rs.close();
ps.close();
con.close();

Обратите внимание на явное отсутствие обработки исключений, оставленное читателю в качестве упражнения.

Если вы хотите больше контролировать количество строк, загружаемых за раз в память, вы можете использовать:

ps.setFetchSize(numberOfRowsToFetch);

Игра с этим может улучшить вашу производительность.

Убедитесь, что у вас есть соответствующий индекс для столбца, который вы используете в ORDER BY, если вам вообще нужна последовательность.

1 голос
/ 20 июля 2011

Так как вы используете Java, основываясь на ваших комментариях:

Если вы используете JDBC, вы захотите использовать: http://download.oracle.com/javase/1.5.0/docs/api/java/sql/ResultSet.html

Если вы используете Hibernate, это становится сложнее: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html

...