Repository navigation
Reuse the JDBC statement of a prepared statement in PgProtocolHandler - #767
Open
trsb-standards wants to merge 1 commit into
Open
trsb-standards wants to merge 1 commit into
trsb-standards wants to merge 1 commit into
Conversation
Execute prepared a new JDBC statement for every Bind+Execute and closed it again afterwards, so a statement the client prepared once was parsed, validated and planned by Calcite again on every execution. Keep the JDBC statement for each statement from Parse, made on its first Execute: later executions clear and bind the parameters and run it again. It is closed when its statement is closed (Close), replaced by a Parse under the same name, or when the connection ends. Keyed by identity, so a statement parsed again under the same name never reuses the old one. A SELECT by key over the PostgreSQL JDBC driver, 1000 executions of one prepared statement: about 8.4 ms per execution before, 0.26 ms after. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Execute prepares a new JDBC statement for every Bind+Execute and closes it right after, so a statement the client prepared once is parsed, validated and planned by Calcite again on every execution. The extended query protocol exists to avoid that, and the PostgreSQL JDBC driver relies on it once a statement passes its prepare threshold.
This keeps the JDBC statement for each statement from Parse, made on its first Execute. Later executions clear and bind the parameters and run the same statement again. It is closed when:
The cache is keyed by statement identity, so a statement parsed again under the same name never reuses the old one.
This was offered as item 4 after #754, which it needed: before #754, a numeric parameter from the JDBC driver failed outright.
Measured with the PostgreSQL JDBC driver: a SELECT by key over a 100-row table, one prepared statement executed 1000 times (
prepareThreshold=1), third round:Tests (in
PgServerTest):testPreparedStatementPreparedOnce: 12 executions of one named statement prepare one JDBC statement on the server's connection. A connection proxy countsprepareStatementcalls.testStatementParsedAgainUnderSameName: withprepareThreshold=0the driver sends every execution as the unnamed statement. Two different queries alternate on it, each returns its own rows, and each Parse prepares anew../mvnw -B test -pl convex-db -am -Dtest='convex.db.**': 192 tests, all pass.One behavioural note: a statement that stays prepared keeps the plan it was prepared with. For a table that changes shape while a client holds a statement on it, this is the same as with a JDBC
PreparedStatementused directly.🤖 Generated with Claude Code