diff --git a/jOOQ-manual/src/main/resources/org/jooq/web/manual-3.11.xml b/jOOQ-manual/src/main/resources/org/jooq/web/manual-3.11.xml index d7a8219a67..10d992840a 100644 --- a/jOOQ-manual/src/main/resources/org/jooq/web/manual-3.11.xml +++ b/jOOQ-manual/src/main/resources/org/jooq/web/manual-3.11.xml @@ -13873,6 +13873,180 @@ x: 2, y: b]]> +
+ Diagnostics + +

+ jOOQ includes a powerful diagnostics SPI, which can be used to detect problems and inefficiencies on different levels of your database interaction: +

+ + + +

+ Just like the , which was documented in the previuos section, this functionality does not depend on using the jOOQ API in a client application, but can expose itself through a JDBC that proxies your real database connection. +

+ + 1")) { + if (rs.next()) + System.out.println("ID: " + rs.getInt(1) + ", title: " + rs.getInt(2)); + } + + // The duplicateStatements() event is triggered. + // --------------------------------------------- + // The statement is the same as the previous one, apart from a different "bind variable". + // Unfortunately, no actual bind variables were used, which may + // 1) hint at a SQL injection risk + // 2) can cause a lot of pressure / contention on execution plan caches and SQL parsers + // + // The tooManyColumnsFetched() event is triggered. + // ----------------------------------------------- + // When iterating the ResultSet, we're actually only ever reading the TITLE column, never + // the ID column. This means we probably should not have projected it in the first place + try (ResultSet rs = s.executeQuery("SELECT id, title FROM book WHERE id > 2")) { + while (rs.next()) + System.out.println("Title: " + rs.getString(2)); + } +}]]> + +

+ This feature incurs a certain overhead over normal operation as it requires: +

+ + + +

+ The following sections describe each individual event, how it can happen, how and why it should be remedied. +

+
+ + +
+ Too Many Rows + +

+ The SPI method handling this event is +

+ +

+ If you're using jOOQ (or an ORM) to eagerly fetch your entire result set, then this will not be a problem in your code base, but when working with jOOQ's or , or as well as with JDBC directly, then it may certainly be possible that client code is aborting the iteration over the entire result set prematurely. +

+ +

+ While it is definitely good not to fetch too many rows from a JDBC ResultSet, it would be even better to communicate to the database that only a limited number of rows are going to be needed in the client, by using the . Not only will this prevent the pre-allocation of some resources both in the client and in the server, but it opens up the possibility of much better execution plans. For instance, the optimiser may prefer to chose nested loop joins over hash joins if it knows that the loops can be aborted early. +

+ +

+ An example is given here: +

+ + + +
+
+ +
+ Too Many Columns + +

+ The SPI method handling this event is +

+ +

+ A common problem with SQL is the high probability of having too many columns in the . This may be due to reckless usage of SELECT * or some refactoring which removes the need to select some of the projected columns, but the query was not adapted. +

+ +

+ If the columns are consumed by some client (e.g. an ORM), then the jOOQ diagnostics have no way of knowing whether they were actually needed or not. But if they are never consumed from the JDBC , then we can say with certainty that too many columns have been projected. +

+ +

+ The drawbacks of projecting too many columns are manifold: +

+ +
    +
  • Too much data is loaded, cached, transferred between server and client. The overall resource consumption of a system is too high if too many columns are projected. This can cause orders of magnitude of overhead in extreme cases!
  • +
  • Locking could occur in cases where it otherwise wouldn't happen, because two conflicting queries actually don't really need to touch the same columns.
  • +
  • The probability of using "covering indexes" (or "index only scans") on some tables decreases because of the unnecessary projection. This can have drastic effects!
  • +
  • The probability of applying JOIN elimination decreases, because of the unnecessary projection. This is particularly true if you're querying views.
  • +
+ +

+ An example is given here: +

+ + + +
+
+
+
+
+
+
+
Logging