过多的列
适用于 ✅ 开源版 ✅ 专业版 ✅ 企业版
处理此事件的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)); } }
反馈
您对此页面有任何反馈吗? 我们很乐意听到您的反馈!