Java 一次使用固定数量的结果流式处理MySql结果集

Java 一次使用固定数量的结果流式处理MySql结果集,java,mysql,sql,Java,Mysql,Sql,我有一个拥有1600万条记录的MySql表,由于一些迁移工作,我正在读取整个MySql表 下面的代码用于在MySql中对大型ResultSet进行流式处理 statement = connection.createStatement( java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); statemen

我有一个拥有1600万条记录的MySql表,由于一些迁移工作,我正在读取整个MySql表

下面的代码用于在MySql中对大型ResultSet进行流式处理

        statement = connection.createStatement(
                java.sql.ResultSet.TYPE_FORWARD_ONLY,
                java.sql.ResultSet.CONCUR_READ_ONLY);
        statement.setFetchSize(Integer.MIN_VALUE);
但这是一次流一个结果,这是否意味着我们每一行都在访问MySql服务器

在使用流媒体时,我们可以设置如下语句


我想在流式传输大型结果集时减少到服务器的往返次数,我假设您使用的是官方MySQL提供的JDBC驱动程序连接器/J

您显式地告诉JDBC(和MySQL)使用
语句.setFetchSize(Integer.MIN_值)逐行流式传输结果

发件人:

默认情况下,结果集被完全检索并存储在内存中。 在大多数情况下,这是最有效的操作方式,并且由于 MySQL网络协议的设计更易于实现。如果 您使用的结果集包含大量行或行 较大的值,并且无法在JVM中为 如果需要内存,您可以告诉驱动程序将结果流式返回 一次一排

要启用此功能,您需要创建一个语句实例 以下列方式:

stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
          java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(Integer.MIN_VALUE);
前向只读结果集与提取结果集的组合 Integer.MIN_值的大小用作向驱动程序发送流的信号 结果按行设置。在此之后,使用 语句将逐行检索

MySQL将忽略除获取大小的
Integer.MIN\u value
以外的任何值,并应用标准行为。整个结果集将由JDBC驱动程序获取


不要使用
setFetchSize()
,这样JDBC驱动程序将使用默认值(
0
),或者显式地将该值设置为
0
。使用
0
的值还将确保JDBC不使用MySQL游标,这可能会发生,具体取决于您的MySQL和Connector/J版本和配置。

要一次使用固定数量的记录(例如,1000批)而不是使用MySQL JDBC驱动程序逐记录流式提取,您需要:

  • 在JDBC URL中将useCursorFetch设置为true,并将defaultFetchSize设置为所需的批处理大小,例如

    jdbc:mysql://localhost/?useCursorFetch=true&defaultFetchSize=1000
    
  • 根据MySQL驱动程序文档,在JDBC URL中将useCursorFetch设置为true,然后在创建语句后调用setFetchSize(1000)。见下面的代码:

    conn = DriverManager.getConnection("jdbc:mysql://localhost/?useCursorFetch=true", "user", "s3cr3t");
    stmt = conn.createStatement();
    stmt.setFetchSize(1000);
    rs = stmt.executeQuery("SELECT * FROM your_table_here");
    

  • 有关更多信息,请参阅官方文档:

    阅读此内容更为相似,这意味着在执行流媒体时无法一次加载1000行左右的数据,对吗?您必须明确您所说的“流媒体”是什么意思。请显示一些代码。我在问,我们是否可以一次流1000行,而不是一行一行地流结果集