Replies: 12 comments 6 replies
-
|
this is an excellent idea. This does not seem particularly difficult in my mind to do from the server POV. Have you looked at what it might take ? |
Beta Was this translation helpful? Give feedback.
-
No, my familiarity with the PostgreSQL source code is mostly limited to examining |
Beta Was this translation helpful? Give feedback.
-
|
I'll try to find some time this week to look at this. |
Beta Was this translation helpful? Give feedback.
-
|
how would you like this implemented |
Beta Was this translation helpful? Give feedback.
-
|
Oh, that's interesting. I hadn't even thought about using I'm not sure about oid vs name. oids are simpler, but names are easier to use. oids require a lookup for non-builtin types like I presume names would be interpreted like So as as user of this feature it doesn't really matter to me, but my guess is oid would be easier to implement. Another question is does |
Beta Was this translation helpful? Give feedback.
-
That would be the predominant use case to be sure. But pgx's type mapping system is entirely pluggable. To pgx the only difference between standard builtin types and UDTs is builtin types are preregistered by default.
Yes, but only in narrow circumstances. pgx supports 5 different query execution modes. The first 4 use the extended protocol.
pgx's default mode uses prepared statements. The other four modes are mostly used when a connection pooler precludes usage of prepared statements. They each provide a different trade off of network round trips, binary format support, parameterized queries vs client side parameter escaping and interpolation, and resilience to a concurrent change to the database schema. This change would improve performance of mode 5, but the big win for me would be in simplifying the extended protocol modes. It might make sense to entirely remove modes 2 and 3 since mode 4 would gain binary format support. |
Beta Was this translation helpful? Give feedback.
-
|
OK, it's somewhat easier to do 5. I'll hack together a patch shortly and see if we get any traction. |
Beta Was this translation helpful? Give feedback.
-
|
@jackc if you have some time can you test this https://github.com/davecramer/postgres/tree/format_binary I'll test it myself but I thought I would throw this up there for you to test |
Beta Was this translation helpful? Give feedback.
-
|
I haven't done any C development in a really long time, and rarely even compile C projects from source. And I can't say I'd ever compiled PostgreSQL from source before either so I had some trepidation trying this. But wow, PostgreSQL is a clean build. It really was just Anyway, your patch worked perfectly for me. Running this program: package main
import (
"context"
"fmt"
"log"
"os"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgproto3"
)
func main() {
ctx := context.Background()
config, err := pgx.ParseConfig(os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
config.DefaultQueryExecMode = pgx.QueryExecModeSimpleProtocol
conn, err := pgx.ConnectConfig(ctx, config)
if err != nil {
log.Fatal(err)
}
defer conn.Close(ctx)
_, err = conn.Exec(ctx, `set format_binary='20,21,23'`)
if err != nil {
log.Fatal(err)
}
conn.PgConn().Frontend().Trace(os.Stdout, pgproto3.TracerOptions{SuppressTimestamps: true})
var n2 int16
var n4 int32
var n8 int64
var s string
err = conn.QueryRow(ctx, `select 1::int2, 2::int4, 3::int8, 'some text'`).Scan(&n2, &n4, &n8, &s)
if err != nil {
log.Fatal(err)
}
fmt.Println(n2, n4, n8, s)
}Got this output: It's definitely sent back in binary from the simple protocol and pgx can understand it. |
Beta Was this translation helpful? Give feedback.
-
|
Ya, the compile (as long as you have the dependencies) is pretty easy. So it would be useful to get some performance numbers before I go to hackers with the patch. Thanks! |
Beta Was this translation helpful? Give feedback.
-
|
So JDBC worked without any changes... now to get some performance measurements. |
Beta Was this translation helpful? Give feedback.
-
|
I did some test benchmarks here: https://github.com/jackc/postgresql_simple_protocol_binary_format_bench It executes a simple select that returns an int4 column, a text column, and a timestamptz column. At 100 rows the text format takes 48% longer than the binary format. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
The binary format can be significantly faster for some data types. Unfortunately, blindly executing a query with all results returned in the binary format is not safe because there is no guarantee the driver understands the binary format for every type the query returns. In addition, setting all results to binary is undesirable as some types are significantly faster in text than binary format (https://github.com/jackc/pg_text_binary_bench).
This means that either the text format must be used or an extra network round trip must be expended for a
Describebefore the query is sent.pgx tries to work around this to some degree by having automatic statement preparation and caching. It works well, but must be disabled when using a connection pooler like PgBouncer.
If the default result formats could be specified, then the binary format could be used more often, with less network overhead, with less driver complexity.
Beta Was this translation helpful? Give feedback.
All reactions