我正在MYSQL的一个表上执行select查询,该表有16,213,156行和10列。但是建立连接后,代码只执行几分钟,然后抛出错误:异常在线程" thread -3“java.lang.OutOfMemoryError: Java堆空间中。
我的系统配置是16 gb内存,Java 8
我尝试将Jvm参数设置为-Xms4G & -Xmx12G。还尝试将stmt.setFetchSize();//设置为10,100,1000仍然相同的错误
我们能用JDBC获取这么多的记录吗?任何帮助都会很感激的。
package com;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import com.opencsv.CSVWriter;
public class Test1 {
private static Connection conn = null;
public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException {
connection();
retrieve(conn);
}
public static void connection()
{
try
{
Class.forName("com.mysql.jdbc.Driver");
String url = "<jdbc connection url>";
conn = DriverManager.getConnection(url, "<username>", "<password>");
System.out.println("Connection established");
}
catch(Exception e)
{
e.printStackTrace();
}
}
public static void retrieve(Connection conn)
{
ResultSet rs = null;
Statement stmt = null;
try
{
stmt = conn.createStatement();
// stmt.setFetchSize(100); // 1000, 10
System.out.println(stmt.getFetchSize()); // By default prints 0
rs = stmt.executeQuery("SELECT * FROM tablename");
CSVWriter writer = new CSVWriter(new BufferedWriter(new FileWriter("C:\\finaldata\\test.csv")));
System.out.println("**** Started writing Data to CSV ****");
int lines = writer.writeAll(rs, true, false, false);
writer.flush();
writer.close();
System.out.println("** OpenCSV -Completed writing the resultSet at " + new Date() + " Number of lines written to the file " + lines);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
发布于 2018-06-24 06:08:11
@MickMnemonic感谢您的帮助,这解决了这个问题。
单独设置fetchSize可能不足以让MySQL驱动程序开始从DB中流数据,而不是一次加载所有数据。你可以试试
stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE);
发布于 2019-07-11 07:07:16
限制查询,比如,
SELECT * FROM message_history limit {start from row no.} , {no. of rows to select}
例子-
SELECT * FROM message_history limit 100000,200000;
将检索从100000到300000的行;类似于将其划分为batches.also
PreparedStatement statement = con.prepareStatement(query);
statement.setFetchSize(Integer.MIN_VALUE);
rs = statement.executeQuery();
这个方法为我检索了2200万条记录。
发布于 2018-06-21 14:08:17
我遇到了一个类似的问题,从MySQL DB读取大约百万行。我正在用一个叫做PreparedStatement的阅读器来阅读。然后,就在PrepareStatement之后,我将获取的大小降到了最小:
PreparedStatement reader = connection.prepareStatement("select....");
reader.setFetchSize(Integer.MIN_VALUE);
从那以后,我就再也不会遇到麻烦了。
https://stackoverflow.com/questions/50953347
复制相似问题