postgres icon indicating copy to clipboard operation
postgres copied to clipboard

sql.unsafe() with params is 3 times slower than sql.unsafe() without params

Open lnlife opened this issue 1 year ago • 4 comments

This results 0.3k qps: await sql.unsafe("select * from posts where id=$1",[5])

This results 1.0k qps: await sql.unsafe("select * from posts where id=5")

lnlife avatar Jan 30 '24 11:01 lnlife

Here is the codes:

const sql = postgres(process.env.PG_URL, { max: 1 })
let r = await sql`select * from posts where id=1`

console.time("sql")
for (let i = 1; i <= 500; i++) {
    r = await sql`select * from posts where id=1`
}
console.timeEnd("sql")

console.time("unsafeWithP")
for (let i = 1; i <= 500; i++) {
    r = await sql.unsafe("select * from posts where id=$1", [1])
}
console.timeEnd("unsafeWithP")

console.time("unsafe")
for (let i = 1; i <= 500; i++) {
    r = await sql.unsafe("select * from posts where id=1")
}
console.timeEnd("unsafe")

results:

[40.56ms] sql
[82.65ms] unsafeWithP
[51.31ms] unsafe

unsafe is always 25% slower than sql, and unsafe with params is more slower.

lnlife avatar Jan 31 '24 00:01 lnlife

Unsafe without parameters default to a simple query which is why it is faster than unsafe with parameters. Unsafe with parameters are not prepared by default, so to get the speed of reguar sql`` you have to use sql.unsafe(..., [...], { prepare: true })

You can also use { prepare: true } for unsafe without parameters.

porsager avatar Jan 31 '24 07:01 porsager

After adding {prepare:true}, sql.unsafe with parameters becomes faster, but sql.unsafe without parameter is still slow, seem {prepared:true} does not affect it.

sql: 48.975ms
unsafeWithP: 52.277ms
unsafe: 64.378ms

Here is the code: r = await sql.unsafe("select * from posts where id=1", [], { prepare: true })

sql.unsafe with out parameter is take higher CPU usage. I have made a benchmark via http multi-concurrency request and it was about 40% slower than sql and sql.unsafe with parameters.

lnlife avatar Jan 31 '24 10:01 lnlife

Perhaps the implicit simple logic takes over. Worth looking into. With prepare: true it should not fall back to a simple query, so this looks like a bug.

porsager avatar Jan 31 '24 10:01 porsager

Queries seem to be executed as expected, and I'm not seeing anything out of the ordinary if I do a proper benchmark with variations and warmup.

porsager avatar Mar 24 '24 13:03 porsager