| From: | Jacob Brazeal <jacob(dot)brazeal(at)gmail(dot)com> |
|---|---|
| To: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | a large LIMIT makes some sorts slower |
| Date: | 2026-07-28 02:09:38 |
| Message-ID: | CA+COZaAT5WbEOUwjmw2RHGDyYf=hPnnR-xf=Fh7S-_x4cg9Zmg@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi hackers,
I found that adding a large LIMIT to a text sort can make the query
substantially slower, even though the executor ultimately uses an ordinary
quicksort rather than a bounded top-N sort.
A reproducer is:
CREATE TABLE sort_test AS
SELECT md5(g::text) AS s
FROM generate_series(1, 3000000) g;
ANALYZE sort_test;
SET work_mem = '1GB';
SET max_parallel_workers_per_gather = 0;
SET jit = off;
Then compare:
EXPLAIN (ANALYZE, COSTS OFF)
SELECT s
FROM sort_test
ORDER BY s COLLATE "C"
LIMIT 1073741823;
with:
EXPLAIN (ANALYZE, COSTS OFF)
SELECT s
FROM sort_test
ORDER BY s COLLATE "C"
LIMIT 1073741824;
Both queries return all 3,000,000 rows, use quicksort, and the same amount
of memory while sorting.
On my build, however, the first query took about 7 seconds and the second
about 2.5 seconds.
The difference is the INT_MAX / 2 check in tuplesort_set_bound(), which comes
from the original abbreviated-key design. The 2014 discussion says
abbreviation was disabled for bounded sorts because it generally did not
pay [0], and a later message describes it as unsuitable for top-N heapsorts.
The problem here is that it is applied when the bound is only a hint,
before tuplesort knows which algorithm it will use.
I did not find a prior report of this large-bound case, where the sort
remains a quicksort but has already lost abbreviation.
Best,
Jacob Brazeal
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Michael Paquier | 2026-07-28 02:11:35 | Re: Quote role name in test/authentication/t/003_peer.pl |
| Previous Message | Michael Paquier | 2026-07-28 02:08:03 | Re: [PATCH v1] Fix propagation of indimmediate flag in index_create_copy |