一次使用固定数量的结果流式传输MySql ResultSet

我有16百万条记录的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服务器

使用流媒体时我们可以设置类似这样的语句.setFetchSize(1000);

我希望在流式传输大型ResultSet时减少到服务器的往返次数

我将假设您正在使用官方MySQL提供的JDBC驱动程序Connector / J.

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

来自MYSQL文档 :

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

要启用此function,您需要以下列方式创建Statement实例:

 stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY); stmt.setFetchSize(Integer.MIN_VALUE); 

只有正向的只读结果集与提取大小Integer.MIN_VALUE的组合用作驱动程序逐行传输结果集的信号。 在此之后,将逐行检索使用该语句创建的任何结果集。

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

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