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

过多的列

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

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

SQL中一个常见的问题是在投影中包含过多的列。这可能是由于不加选择地使用SELECT *,或者某些重构删除了选择某些投影列的需求,但查询未进行调整。

如果这些列被某些客户端(例如ORM)使用,那么jOOQ诊断无法知道它们是否真正需要。但是,如果它们从未从JDBC java.sql.ResultSet 中使用,那么我们可以肯定地说投影了过多的列。

为什么这不好?

投影过多列的缺点有很多

  • 加载、缓存、服务器和客户端之间传输的数据太多。如果投影了太多的列,系统的整体资源消耗就会过高。在极端情况下,这可能会导致数量级的开销!
  • 在某些情况下,可能会发生锁定,而原本不会发生,因为两个冲突的查询实际上并不需要访问相同的列。
  • 由于不必要的投影,在某些表上使用“覆盖索引”(或“仅索引扫描”)的概率降低。这可能会产生严重的影响!
  • 由于不必要的投影,应用JOIN消除的概率降低。如果您正在查询视图,则尤其如此。

这里给出了一个例子

// A custom DiagnosticsListener SPI implementation
class TooManyColumns implements DiagnosticsListener {
    @Override
    public void tooManyColumnsFetched(DiagnosticsContext ctx) {
        System.out.println("Consumed columns: " + ctx.resultSetConsumedColumnCount());
        System.out.println("Fetched columns: " + ctx.resultSetFetchedColumnCount());
    }
}

然后

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

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

        // On none of the rows, we retrieve the TITLE column, so selecting it would not have been necessary.
        while (rs.next())
            System.out.println("ID: " + rs.getInt(1));
    }
}

反馈

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

The jOOQ Logo