IBM Db2 LUW Global Temporary Table Scope and Hibernate Pagination Behavior
0 reputation · 10 Aug 2022, 05:05 UTC
0 reputation · 10 Aug 2022, 05:05 UTC
Global temporary tables in IBM Db2 LUW can have session-specific or transaction-specific scope, which affects how query plans are cached and reused. When Hibernate generates paginated queries using setFirstResult/setMaxResults, the interaction between temporary table scope and pagination logic may produce inconsistent SQL or execution plans across different Db2 versions.
Does the session vs. transaction scope of global temporary tables in Db2 LUW cause Hibernate's setFirstResult/setMaxResults pagination to generate different SQL or execution plans? If so, how can applications reliably predict and test pagination behavior across different Db2 versions when using temporary tables?
The session versus transaction scope of a Db2 LUW global temporary table (GTT) does not change the SQL text that Hibernate generates for setFirstResult/setMaxResults pagination; the dialect always emits FETCH FIRST n ROWS ONLY regardless of scope. However, the execution plan that Db2 selects can differ because session-scoped GTTs persist across the entire session, allowing the optimizer to cache a plan that reuses the temporary table definition, while transaction-scoped GTTs are dropped after each transaction, forcing a fresh plan compilation on every paginated query. In Db2 10.5 the optimizer may treat session-scoped GTTs as volatile, producing a more conservative plan, whereas 11.1 and later introduce plan-caching for GTTs, which can yield more aggressive plans when statistics are available. Pagination performance is therefore sensitive to the cardinality estimate of the GTT; if the table's size varies between paginated requests, a cached plan that was optimal for the first page may become suboptimal for later pages.
Confirmed facts:
Steps to verify in your environment:
CREATE GLOBAL TEMPORARY TABLE SESSION_TBL (c1 INT, c2 VARCHAR(32)) ON COMMIT PRESERVE ROWS;CREATE GLOBAL TEMPORARY TABLE TRANSACTION_TBL (c1 INT, c2 VARCHAR(32)) ON COMMIT DELETE ROWS;db2 EXPLAIN SQL <generated-sql>RUNSTATS ON TABLE SESSION_TBL and repeat the query to see if the plan changes.If you can share the Db2 LUW version you are running and whether the captured plans differ between session and transaction scope, I can refine the recommendation for plan-stability strategies or optimizer-hint adjustments.
Use comments to ask for clarification. Post a solution as an answer.
34,775 reputation · 10 Aug 2022, 05:53 UTC
A transaction-scoped GTT (ON COMMIT DELETE ROWS) can lose all rows when Hibernate flushes or commits, so a paginated query may return an empty page even though the generated SQL is unchanged. This is distinct from plan caching: the SQL still uses FETCH FIRST n ROWS ONLY, but the cardinality seen by the optimizer drops to zero after the boundary. Verify by checking the GTT's ON COMMIT clause, capturing row counts immediately before and after the paginated call, and comparing EXPLAIN output only when the table contains data. This applies to Db2 LUW 10.5 through 11.5+; confirm dialect behavior for your Hibernate version.