一次传输固定数量结果的 MySql ResultSet

Ram*_*ams 5 java mysql sql

我有包含 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);
Run Code Online (Sandbox Code Playgroud)

但这是一次流式传输一个结果,这是否意味着我们正在为每一行访问 MySql 服务器

在使用流式传输时,我们可以设置类似这样的语句:setFetchSize(1000);

我想在流式传输大型结果集时减少到服务器的往返次数

Mar*_*ams 5

我假设您使用的是 MySQL 官方提供的 JDBC 驱动程序 Connector/J。

您明确告诉 JDBC(和 MySQL)逐行流式传输结果statement.setFetchSize(Integer.MIN_VALUE);

来自MYSQL 文档

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

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

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

只进、只读结果集与获取大小 Integer.MIN_VALUE 的组合充当驱动程序的信号,以逐行流式传输结果集。此后,将逐行检索使用该语句创建的任何结果集。

Integer.MIN_VALUEMySQL 会忽略除获取大小之外的任何值,并应用标准行为。整个结果集将由 JDBC 驱动程序获取。

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

  • 我问的是,我们是否可以一次流式传输 1000 行,而不是逐行流式传输结果集 (3认同)
  • 这意味着在进行流式处理时无法一次加载 1000 行左右,对吗? (2认同)