【问题标题】:Writing Data from RDS to Disk in JOOQ在 JOOQ 中将数据从 RDS 写入磁盘
【发布时间】:2019-01-09 00:26:00
【问题描述】:

我的用例是我必须在 RDS 实例上运行查询,它返回 200 万条记录。现在,我想将结果直接复制到磁盘,而不是将其放入内存然后再复制到磁盘。

下面的语句将把所有的记录都带入内存,我想直接将结果传输到磁盘上的文件中。

SelectQuery<Record> abc = dslContext.selectQuery().fetch();

谁能推荐一个指针?

更新1:
我找到了以下阅读方式:

try (Cursor<BookRecord> cursor = create.selectFrom(BOOK).fetchLazy()) {
    while (cursor.hasNext()){
        BookRecord book = cursor.fetchOne();
        Util.doThingsWithBook(book);
    }
}

它一次提取多少条记录,这些记录是先带入内存的吗?

更新 2:
默认情况下,MySQL 驱动程序一次获取所有记录。如果 fetch size 设置为 Integer.MIN_VALUE 那么它一次获取一条记录。如果要批量获取记录,请在设置连接属性时设置 useCursorFetch=true。
相关维基:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-implementation-notes.html

【问题讨论】:

  • 我假设“RDS”是Amazon RDS(纠正我,否则)。乍一看,您的问题似乎是“如何从云数据库实例中读取数据并将结果直接写入磁盘而不通过内存?”......但是,考虑到预期的数据量,您实际上是在问如何避免一次获取整个结果集,而是分块读取? (即分页)
  • 是的,我说的是 Amazon Aurora。是的,我不必对结果集进行任何处理,只需将其写入磁盘即可。是的,我想分块读取它,但这些块也会先进入内存吗?

标签: java sql jooq


【解决方案1】:

您使用ResultQuery.fetchLazy() 方法的方法是jOOQ 从JDBC 一次获取一条记录的方法。请注意,您也可以使用Cursor.fetchNext(int) 从 JDBC 中获取一批记录。

您可能需要配置第二件事,那就是 JDBC 提取大小,请参阅 Statement.setFetchSize(int)。这配置了 JDBC 驱动程序在单个批次中从服务器获取多少行。根据您的数据库/ JDBC 驱动程序(例如 MySQL),默认设置将再次一次获取所有行。要在 jOOQ 查询上指定 JDBC 提取大小,请使用 ResultQuery.fetchSize(int)。所以你的循环会变成:

try (Cursor<BookRecord> cursor = create
        .selectFrom(BOOK)
        .fetchSize(size)
        .fetchLazy()) {
    while (cursor.hasNext()){
        BookRecord book = cursor.fetchOne();
        Util.doThingsWithBook(book);
    }
}

请阅读您的 JDBC 驱动程序手册,了解他们如何解释提取大小,noting that MySQL is "special"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-12
    • 1970-01-01
    • 2011-12-13
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    • 2020-07-03
    • 1970-01-01
    相关资源
    最近更新 更多