From: | Matt Silverlock <matt(at)eatsleeprepeat(dot)net> |
---|---|
To: | "pgsql-performance(at)postgresql(dot)org" <pgsql-performance(at)postgresql(dot)org> |
Cc: | Merlin Moncure <mmoncure(at)gmail(dot)com>, Jeff Janes <jeff(dot)janes(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Subject: | Re: OFFSET/LIMIT - Disparate Performance w/ Go application |
Date: | 2014-06-12 22:39:43 |
Message-ID: | 7B027793-2097-4309-A754-BB82B3A5EFD9@eatsleprepeat.net |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-performance |
Thanks for the replies Jeff, Tom and Merlin.
>> Pages that SELECT multiple rows with OFFSET and LIMIT conditions struggle to top 1.3k req/s
>
> Is that tested at the OFFSET and LIMIT of 0 and 15, as shown in the
> explain plan?
Yes — 0 (OFFSET) and 16 (LIMIT), or 15 and 31 (i.e. “second page” of results). There’s no difference on that front. For context, OFFSET is a multiple of 15 (i.e. 15 results per page) and LIMIT is always 15 + 1 in an attempt to fetch one more result, get the len of the returned slice and then return paginate true + slice the last result off if there’s more than 15.
>
>
>> The query in question is: http://explain.depesz.com/s/7g8 and the table schema is as below:
>
> The reported runtime of 0.078 ms should be able to sustain nearly 10
> times the reported rate of 1.3k/s, so the bottleneck would seem to be
> elsewhere.
>
> Perhaps the bottleneck is formatting the result set in postgres to be
> sent over the wire, then sending it over the wire, then parsing it in
> the Go connection library to hand back to the Go user code, and then
> the Go user code doing something meaningful with it.
>
> What happens if you get rid of the offset and the order by, and just
> use limit? I bet it doesn't change the speed much (because that is
> not where the bottleneck is).
>
> You seem to be selecting an awful lot of wide columns. Do you really
> need to see all of them?
- Testing SELECT * FROM … with just LIMIT 15 and no offset yields 1299 request/s at the front end of the application.
- Testing SELECT id, title, company, location, commute, term, expiry_date (a subset of fields) with LIMIT 15 and no OFFSET yields 1800 request/s at the front end.
There’s definitely an increase to be realised there (I’d say by just tossing the rendered HTML field).
Based on your comments about the Go side of things, I ran a quick test by cutting the table down to 6 records from the 39 in the test DB in all previous tests. This skips the pagination logic (below) and yields 3068 req/s on the front-end.
// Determine if we have more than one page of results.
// If so, trim the extra result off and set pagination = true
if len(listings) > opts.PerPage {
paginate = true
listings = listings[:opts.PerPage]
}
So there certainly appears to be a bottleneck on the Go side as well (outside of even the DB driver), probably from the garbage generated from slicing the slice, although I’d be keen to know if there’s a better way to approach returning a paginated list of results.
>>> Well, you can also do client side pagination using the row-wise
>>> comparison feature, implemented by you :-). Cursors can be the best
>>> approach, but it's nice to know the client side approach if you're
>>> really stateless and/or want to be able to pick up external changes
>>> during the browse.
What would be a better approach here? The cursor approach isn’t ideal in my case (although I could make it work), but what other options are there that are stateless?
>>
>> Some pgbench results from this machine as well:
>>
>> $ pgbench -c 128 -C -j 4 -T 15 -M extended -S
>
> This is just benchmarking how fast you can make and break connections
> to the database.
>
> Because your app is using an embedded connection pooler, this
> benchmark isn't very relevant to your situation.
Noted — thanks.
On 13 Jun 2014, at 4:46 AM, Jeff Janes <jeff(dot)janes(at)gmail(dot)com> wrote:
> <snip>
From | Date | Subject | |
---|---|---|---|
Next Message | Tim Kane | 2014-06-13 07:19:19 | Re: postgres files in use not staying in linux file cache |
Previous Message | Jeff Janes | 2014-06-12 20:46:48 | Re: OFFSET/LIMIT - Disparate Performance w/ Go application |