Java 如何在结果集中检索超过 100 万行

Vik*_*s J 5 java jdbc

我正在对一个 MYSQL 表执行选择查询,该表有 16,213,156 行和 10 列。但是在建立连接后,代码只执行几分钟,然后抛出错误:线程“Thread-3”中的异常 java.lang.OutOfMemoryError: Java heap space

我的系统配置是 16 GB RAM,Java 8

我尝试将 Jvm 参数设置为 -Xms4G & -Xmx12G 。还尝试设置 stmt.setFetchSize(); // 到 10,100,1000 仍然是同样的错误

我们可以使用 JDBC API 获取如此大量的记录吗?我错过了什么吗?任何帮助将非常感激。

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Vik*_*s J 5

@MickMnemonic 感谢您的帮助解决了这个问题。

单独设置fetchSize可能不足以让 MySQL 驱动程序开始从数据库流式传输数据,而不是一次加载所有内容。你可以试试

stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE);
Run Code Online (Sandbox Code Playgroud)