Re: Top-N sorts verses parallelism

From: Robert Haas <robertmhaas(at)gmail(dot)com>
To: Thomas Munro <thomas(dot)munro(at)enterprisedb(dot)com>
Cc: Pg Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Top-N sorts verses parallelism
Date: 2017-12-13 21:53:46
Message-ID: CA+TgmoZ9Q=+mUUgcJGbghoD9J8T5SOjHbcRDoc+fPiV-OvXrvg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, Dec 13, 2017 at 1:46 AM, Thomas Munro
<thomas(dot)munro(at)enterprisedb(dot)com> wrote:
> Hi hackers,
>
> The start-up cost of bounded (top-N) sorts is sensitive at the small
> end of N, and the
> comparison_cost * tuples * LOG2(2.0 * output_tuples) curve doesn't
> seem to correspond to reality. Here's a contrived example that comes
> from a benchmark:
>
> create table foo as
> select generate_series(1, 1000000)::int a, (random() * 1000)::int b;
> analyze foo;
> select * from foo order by b limit N;
>
> But the actual time doesn't really change on this random development
> system: it's around 300ms. I stopped at limit 133 because for this
> particular query, at 134 a Gather Merge plan kicked in and I got
> degree 3 parallel sorting and I got my answer just shy of three times
> faster. The speed up definitely paid for the parallel_setup_cost and
> only one tuple was sent from each worker to the leader because the
> limit was pushed down.

I get:

rhaas=# explain analyze select * from foo order by b limit 1;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Limit (cost=19425.00..19425.00 rows=1 width=8) (actual
time=183.129..183.129 rows=1 loops=1)
-> Sort (cost=19425.00..21925.00 rows=1000000 width=8) (actual
time=183.128..183.128 rows=1 loops=1)
Sort Key: b
Sort Method: top-N heapsort Memory: 25kB
-> Seq Scan on foo (cost=0.00..14425.00 rows=1000000
width=8) (actual time=0.046..89.440 rows=1000000 loops=1)
Planning time: 0.083 ms
Execution time: 183.171 ms
(7 rows)

If we assume the costing of the Seq Scan node is right, then the
startup cost of the Sort node is too low. For the Seq Scan node, each
1ms of execution time corresponds to 161.28 cost units. If that were
accurate, then the 183.128 - 89.440 = 93.668 cost units of startup
cost for the Sort ought to have a cost of 14425.00 + (93.668 * 161.28)
= 29531.77504, but the actual cost is only 19425.00. In other words,
the ratio of the startup cost of the sort to the total cost of the seq
scan ought to be about 2:1, to match the ratio of the execution times,
but it's actually more like 4:3.

I also see that it switches to Gather Merge at LIMIT 134, but if I
lower random_page_cost and seq_page_cost from the default values to
0.1, then for me it switches earlier, at 63. Of course, at that point
the sort cost is now 3.5x the Seq Scan cost, so now things have gone
too far in the other direction and we're still not getting the plan
right, but I am out of time to investigate this for the moment.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Jeff Janes 2017-12-13 21:55:09 Re: Top-N sorts verses parallelism
Previous Message Peter Geoghegan 2017-12-13 21:45:45 Re: heap/SLRU verification, relfrozenxid cut-off, and freeze-the-dead bug (Was: amcheck (B-Tree integrity checking tool))