pgsql-hackers
❮
slow SELECT expr INTO var in plpgsql
- Jump to comment-1Pavel Stehule<pavel.stehule@gmail.com>Jan 31, 2026, 6:52 AM UTCHi
I found a article
https://medium.com/google-cloud/postgresql-performance-the-context-switch-trap-that-slows-down-t-sql-migrations-7b8c6f518fd8
It compare T-SQL and PLpgSQL performance on some simple benchmark
do $$ declare x int; begin for i in 1..10000000 loop x := 0; end loop; end
$$;
do $$ declare x int; begin for i in 1..10000000 loop select 0 into x; end
loop; end $$;
I remember the old discussion about this issue, and I thought that theSELECT expr INTO var is syntax used on old sybase and mssql systems. The positive result in this article is fact, so Postgres in all tests are very well comparable. More - the assignment is really fast and significantly faster than on MSSQL.
performance of SELECT INTO and assignment should be almost the same. I
repeated these tests on pg 9.4, 11 and master (asserts are disabled) with
interesting results
release, assign time, select into time
9.4, 2900 ms, 20800 ms
11, 2041 ms, 16243 ms
master, 534ms, 15438 ms
Originally, I used gcc with O0, and master is really slow without O2
optimization
9.4, 2600 ms, 20800 ms --<< 9.4 is faster with O0
11, 2177 ms, 19128 ms
master, 1395 ms, 70060 ms -- << master is very slow with O0
Using SELECT expr INTO var is plpgsql's antipattern. plpgsql_check can
detect it now. But it will still be nice if there will not be too big a
difference like now. I didn't check the code yet, and I have no idea if
there are some possibilities on how to execute this case better.
Regards
Pavel
tested on Fedora 43- Jump to comment-1Tom Lane<tgl@sss.pgh.pa.us>Jan 31, 2026, 8:58 PM UTCPavel Stehule <pavel.stehule@gmail.com> writes:
I remember the old discussion about this issue, and I thought that the
performance of SELECT INTO and assignment should be almost the same. I
repeated these tests on pg 9.4, 11 and master (asserts are disabled) with
interesting resultsrelease, assign time, select into time
Yeah, we've sweated a good deal about optimizing plpgsql assignment,
9.4, 2900 ms, 20800 ms
11, 2041 ms, 16243 ms
master, 534ms, 15438 ms
but SELECT INTO is always done the hard way.
I experimented a little bit with converting simple-expression
* SELECT INTO is tracked by pgstatstatements, assignments aren't.SELECT INTO into an assignment, as attached. It does reclaim nearly all of the performance difference: for me, these two test cases now take about 276 vs 337 ms. However, I'm concerned about the side-effects of substituting this other code path; there's a lot of potential minor differences in behavior. Two that you can see in the regression test changes are:
* The context report for an error can be different, because
SPIerror_callback() doesn't get used.
We could probably eliminate the context-report difference by setting
up a custom error context callback in this new code path, but the
difference in pgstatstatements output would be hard to mask.
There may be other discrepancies as well, such as variations in
error message wording.
Probably no one would notice such details if it had been like that
all along, but would they complain about a change? I dunno.regards, tom lane