Как записать огромные данные в текстовом файле, используя JDBC без нехватки памяти - PullRequest
2 голосов
/ 25 августа 2009

Я пытаюсь создать файл дампа из базы данных, используя JDBC. Файл должен иметь размер около 300 МБ и содержать от 1,2 до 1,5 миллионов записей в десяти столбцах, но у меня не хватает памяти около 250 тысяч.

Мой вопрос: сохраняет ли java весь набор записей в памяти? Я установил, что набор записей будет доступен только для чтения, в надежде, что уже сброшенные записи будут удалены из памяти, но это не так.

Любая помощь будет принята с благодарностью.

Ответы [ 4 ]

7 голосов
/ 25 августа 2009

Вы должны использовать setFetchSize для объекта Statement. В следующем примере будет извлекаться только 1000 записей одновременно из ResultSet:

Connection con = DriverManager.getConnection("jdbc:my_subprotocol:my_subname");
Statement stmt = con.createStatement();
stmt.setFetchSize(1000);
ResultSet rs = stmt.executeQuery("SELECT * FROM your_table");

Вот этот Javadoc:

http://java.sun.com/javase/6/docs/api/java/sql/Statement.html#setFetchSize(int)

1 голос
/ 25 августа 2009

Если вы извлекаете все данные, а затем записываете в файл в качестве второго шага, наступит момент, когда все данные БД будут в памяти. Если вы передадите данные в файл, этого не произойдет. вместо

data=...
while (rs.next()){
  ... add rs value to data
}
..write data to file

что-то вроде

file=...
while (rs.next()){
  write rs to file
}
0 голосов
/ 25 августа 2009

Установка fetchSize должна помочь. Но на самом деле это зависит от драйвера JDBC. Но вы можете читать данные итеративно (небольшими порциями):

stm = conn.prepareStatement("...where id > ? order by id");
stm.setMaxRows(100);

while(true) {
    stm.setInt(1, lastId);
    ResultSet results = stm.executeQuery();

    // process results and assign a new value to lastId 

    rs.close();
}
0 голосов
/ 25 августа 2009

Поведение буфера / освобождения выборки зависит от драйвера JDBC, а также сборщика мусора JVM. Делаете ли вы какую-либо буферизацию перед записью в FileOutputStream (это может помешать сборке мусора в памяти)?

Попробуйте настроить размер кучи Java с помощью аргументов времени выполнения Java -Xms и -Xmx. Пример:

java -Xms1024M -Xmx1024M com.mypkg.MyResultSetReader

Приведенная выше команда выделит для вашей программы 1 ГБ пространства кучи. Если это временный инструмент или вы не ожидаете увеличения размера ResultSet, это может работать как постоянное решение.

...