Re: Inefficient SELECT with OFFSET and LIMIT

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Greg Stark <gsstark(at)mit(dot)edu>
Cc: Clive Page <cgp(at)leicester(dot)ac(dot)uk>, pgsql-performance(at)postgresql(dot)org
Subject: Re: Inefficient SELECT with OFFSET and LIMIT
Date: 2004-01-06 18:36:44
Message-ID: 22305.1073414204@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-performance

Greg Stark <gsstark(at)mit(dot)edu> writes:
> Clive Page <cgp(at)leicester(dot)ac(dot)uk> writes:
>> It would be nice if OFFSET could be implemented in some more efficient
>> way.

> You could do something like:

> select myfunc(mycol) from (select mycol from table limit 50 offset 10000) as x;

Note that this won't eliminate the major inefficiency, which is having
to read 10000+50 rows from the table. But if myfunc() has side-effects
or is very expensive to run, it'd probably be worth doing.

> I think it's not easy for the optimizer to do it because there are lots of
> cases where it can't.

I don't actually know of any cases where it could do much of anything to
avoid fetching the OFFSET rows. The problems are basically the same as
with COUNT(*) optimization: without examining each row, you don't know
if it would have been returned or not. We could possibly postpone
evaluation of the SELECT output list until after the OFFSET step (thus
automating the above hack), but even that only works if there are no
set-returning functions in the output list ...

regards, tom lane

PS: BTW, the one-extra-row effect that Clive noted is gone in 7.4.

In response to

Browse pgsql-performance by date

  From Date Subject
Next Message Mark Kirkwood 2004-01-06 19:28:45 Re: Select max(foo) and select count(*) optimization
Previous Message Greg Stark 2004-01-06 18:12:17 Re: Inefficient SELECT with OFFSET and LIMIT