当前位置: 首页 > 知识库问答 >
问题:

流式传输 MySql 结果集,一次具有固定数量的结果

贺佑运
2023-03-14

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

以下代码用于在MySql中流式传输大型结果集

        statement = connection.createStatement(
                java.sql.ResultSet.TYPE_FORWARD_ONLY,
                java.sql.ResultSet.CONCUR_READ_ONLY);
        statement.setFetchSize(Integer.MIN_VALUE);

但这是一次流式传输一个结果,这是否意味着我们每行都命中MySql服务器

在使用流时,我们可以设置如下语句:setFetchSize(1000);

我想减少到服务器的往返次数,同时流式传输大型 ResultSet

共有2个答案

万知
2023-03-14

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

>

  • 将useCursorFetch设置为true,将defaultFetchSize设置为JDBC URL中所需的批大小,例如:。

    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");
    

    有关更多信息,请参阅官方文档:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-implementation-notes.html

  • 贺善
    2023-03-14

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

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

    从MYSQL文档:

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

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

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

    前向只读结果集与整数获取大小的组合。MIN_VALUE用作驱动程序的信号,以逐行流式传输结果集。之后,将逐行检索使用该语句创建的任何结果集。

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

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

     类似资料:
    • 问题内容: 我有包含1600万条记录的MySql表,由于某些迁移工作,我正在读取整个Mysql表。 以下代码用于在MySql中流式传输大型ResultSet 但这一次一次流式传输一个结果,这是否意味着我们在每一行都命中了MySql服务器 在使用流式传输时,我们可以设置以下语句吗?setFetchSize(1000); 我想减少流式传输大型ResultSet时往返服务器的次数 问题答案: 我将假定您

    • 问题内容: 我正在开发一个使用大型MySQL表的spring应用程序。加载大表时,我得到一个,因为驱动程序试图将整个表加载到应用程序内存中。 我尝试使用 但是然后我打开的每个ResultSet都挂了; 在网上查看时,我发现发生这种情况是因为它尝试在关闭ResultSet之前尝试加载所有未读的行,但事实并非如此,因为我这样做是: 小表(3行)也会发生挂起,如果我不关闭RecordSet(在一种方法中

    • 根据我的阅读,我认为使用MySQL JDBC驱动程序在MySQL中流式传输< code>ResultSet的方法是这两个命令: 我的问题是,专家能否澄清使用上述代码流式传输ResultSet是否会将一行返回给客户端,然后去服务器获取下一行,依此类推(效率非常低),或者它是否足够智能,可以像一样进行缓冲流式传输?如果它进行缓冲流式传输,如何设置缓冲区大小? 编辑:来自文档: 前向只读结果集与整数获取

    • MySQL JDBC 连接器定义了两种提取模式: < li >默认的一次获取整个结果集 < li >流,当语句fetchSize设置为整数时。最小值 根据文档,流将单独获取每一行,一次一行。 > 使用流时,每一行都在单独的数据库往返中获取,这是真的吗? MySQL服务器是预先预取结果集,还是一次遍历服务器端游标的一行?

    • 我不知道这个错误意味着什么,也不知道如何修复它。我试图从我的一个数据库中检索一些数据,但一直遇到下面的错误消息。

    • 我使用的是spring data mongodb,我想使用光标进行聚合操作。 MongoTemplate.stream()得到一个查询,所以我尝试创建聚合实例,使用ggregation.toDbObject()将其转换为DbObject,使用DbObject创建BasicQuery,然后调用stream()方法。 这返回一个空光标。 调试spring数据mongodb代码显示MongoTempla