可用版本:Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

行数过多

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

处理此事件的 SPI 方法是 tooManyRowsFetched()

如果您使用 jOOQ(或 ORM)来急切地获取您的整个结果集,那么这在您的代码库中不会是一个问题,但是当使用 jOOQ 的 延迟获取 API延迟流式传输支持,以及直接使用 JDBC java.sql.ResultSet 时,客户端代码可能过早地中止整个结果集的迭代。

为什么这不好?

虽然不从 java.sql.ResultSet 中获取过多行肯定是好的,但最好通过使用 LIMIT 子句来告知数据库客户端只需要有限数量的行。这不仅可以防止在客户端和服务器中预先分配一些资源,而且还打开了更好执行计划的可能性。例如,如果优化器知道循环可以提前中止,则可能会选择嵌套循环连接而不是哈希连接。

这里给出了一个例子

// A custom DiagnosticsListener SPI implementation
class TooManyRows implements DiagnosticsListener {
    @Override
    public void tooManyRowsFetched(DiagnosticsContext ctx) {
        System.out.println("Consumed rows: " + ctx.resultSetConsumedRows());

        // This incurs overhead by consuming the ResultSet! Use only if needed.
        System.out.println("Fetched rows: " + ctx.resultSetFetchedRows());
    }
}

然后

// Configuration is configured with the target DataSource, SQLDialect, etc. for instance Oracle.
try (Connection c = DSL.using(configuration.derive(new TooManyRows()))
                       .diagnosticsConnection();
     Statement s = c.createStatement()) {

    try (ResultSet rs = s.executeQuery("SELECT id FROM book")) {

        // Unlike "while", "if" only consumes the first row, here.
        if (rs.next())
            System.out.println("ID: " + rs.getInt(1));
    }
}

反馈

您对此页面有任何反馈吗? 我们很乐意听取您的意见!

The jOOQ Logo