-
-
Notifications
You must be signed in to change notification settings - Fork 978
Skip Describe portal when executing prepared statements #2422
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
And even faster impl of readUntilRowDescription (7-11% faster): Changes:
|
3a0c941 to
c801b0a
Compare
|
I just added support for skipping Describe to pgconn.Batch. I also restructured some of the row and field description handling including taking some of the optimizations that @analytically posted above. As of this change there is no more worry about concern "2", what happens if someone changes a prepared statement description concurrently, as it is no longer shared. This functionality is still not available in pgx.Batch. It would still need to be implemented in pgconn.Pipeline as pgx.Batch uses that instead of pgconn.Batch. |
Refactor row / field description handling.
Queue execution of prepared statement without describing portal in pipeline mode. Ugly and hacky but works for now.
Now delegates to specific methods for each request type.
This reduces redundant protocol messages when the statement description is already known.
edf0221 to
228c905
Compare
|
I've just pushed the implementation for skipping Describe portal with pipeline mode and wired up pgx to use the new functionality. It also includes a number of refactorings and cleanups. I am inclined to merge this, but it would be good to have some additional people try it out first. |
This is a proof of concept for skipping
Describeportal message when executing a prepared statement.Currently, pgx always sends a
Describeportal message when executing a prepared statement. It receives aRowDescriptionmessage in response. This is convenient as result sets always include aRowDescriptionfirst regardless of whether the query was executed with the simple protocol, the extended protocol without a prepared statement, or the extended protocol with a prepared statement.But pgx always
Describeprepared statements when it creates them. So it already has theRowDescription. The only thing it lacks is the format (text or binary) of the result fields as that is specified per execution. But if pgx remembered the formats it requested when it sent the query it could synthesize the completeRowDescriptionwithout needing to ask PostgreSQL to resend it.This proof of concept adds a new method,
*PgConn.ExecPreparedStatementDescription()that tests this approach.Here are results of one of the existing benchmarks adapted to use the new method along with the original method:
There is a tiny improvement in runtime, on the order of a few 100ns to a 1000ns. Per query memory usage and allocations are reduced by an amount significant to this benchmark. Whether it is significant in the context of an application is another question.
It also reduces the amount of network traffic. The test
TestConnExecPreparedStatementDescriptionNetworkUsagemeasures the bytes written and read to the PostgreSQL server using the same query used in the benchmark above when returning a single row.The amount of bytes written to the server only varies by 7 bytes, 54 without
Describeand 61 withDescribe. But the bytes received varies by 238 bytes, 153 withoutDescribeand 391 withDescribe. That is 2.55x received bytes.The percentage change will vary significantly based on the number of columns in the result set, which determines the size of the
RowDescriptionmessage, and the number of rows returned. If only one row is returned it is quite likely thatRowDescriptionis bigger than the actual data. But if many rows are returned then theRowDescriptioncost is insignificant.Considerations for whether to move forward with this approach:
Describeportal message. See https://github.com/postgres/postgres/blob/master/src/interfaces/libpq/fe-exec.c#L1883-L1895. We may run into edge cases with PostgreSQL as no one else may be doing this. In addition, it may cause compatibility issues with semi-compatible databases like CRDB.