MagicStack / asyncpg

A fast PostgreSQL Database Client Library for Python/asyncio.
Apache License 2.0
6.88k stars 399 forks source link

Difference between bulk update with FROM VALUES and without it? #1055

Open wowka1319 opened 1 year ago

wowka1319 commented 1 year ago
await conn.executemany(
    """
    UPDATE user SET login=$2, name=$3, age=$4, sex=$5
    WHERE id=$1
    """,
    users,
)
await conn.executemany(
    """
    UPDATE user SET login=actual_user.login, name=actual_user.name, age=actual_user.age, sex=actual_user.sex
    FROM (VALUES ($1, $2, $3, $4, $5)) AS actual_user (id, login, name, age::integer, sex::integer)
    WHERE user.id=actual_user.id
    """,
    users,
)

The first is cleaner. But I worry about performance. I know the second is performed as one request. But the first is the same?

Is there any reason to use the second way?

elprans commented 1 year ago

I don't think FROM VALUES buys you anything here, and it could actually be slightly worse.

I know the second is performed as one request

Not quite simple as that. executemany() is a pipelined operation, and so while the query is parsed and prepared only once, it is executed as many times as there are items in the users iterable. However, since asyncpg does not wait for the result of each execution and continues pumping the arguments this is almost as fast as sending the entire argument set at once.