Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UR2Vn-0001wV-6f for pgsql-performance@arkaria.postgresql.org; Sat, 13 Apr 2013 15:37:07 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.72) (envelope-from ) id 1UR2Vm-0000sT-KK for pgsql-performance@arkaria.postgresql.org; Sat, 13 Apr 2013 15:37:06 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UR2Vl-0000sN-Jg for pgsql-performance@postgresql.org; Sat, 13 Apr 2013 15:37:05 +0000 Received: from ipmail06.adl6.internode.on.net ([2001:44b8:8060:ff02:300:1:6:6]) by magus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1UR2Vb-0002H3-EZ for pgsql-performance@postgresql.org; Sat, 13 Apr 2013 15:37:04 +0000 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AjgDAC96aVF20a7S/2dsb2JhbAANQ8Iigl8EAwGBGoMTAQEBBCdREQsYCRYPCQMCAQIBRRMIArA7kwaNYIE+FoMrA45dhFuNVYomgVk Received: from ppp118-209-174-210.lns20.mel6.internode.on.net (HELO [192.168.1.4]) ([118.209.174.210]) by ipmail06.adl6.internode.on.net with ESMTP; 14 Apr 2013 01:06:49 +0930 Message-ID: <51697B90.1000603@internode.on.net> Date: Sun, 14 Apr 2013 01:36:48 +1000 From: Julian User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130116 Icedove/10.0.12 MIME-Version: 1.0 To: pgsql-performance@postgresql.org Subject: Re: limit is sometimes not pushed in view with order References: <5169168D.4000903@ngs.hr> In-Reply-To: <5169168D.4000903@ngs.hr> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Pg-Spam-Score: -4.3 (----) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-performance Precedence: bulk Sender: pgsql-performance-owner@postgresql.org On 13/04/13 18:25, Rikard Pavelic wrote: > I was investigating some performance issues and stumbled upon this behavior: > > create table main_table (i serial primary key, data varchar, ord int); > create view main_view_order as select m.i, m.data, m.ord from main_table m order by m.i desc; > > insert into main_table select i, i::text, i/10 from generate_series(1,1000000) i; > > create index ix_ord on main_table(ord); > analyze main_table; > > explain analyze select * from main_view_order m where m.ord >= 5000 and m.ord <= 5500 limit 10; > > Limit (cost=0.00..69.01 rows=10 width=14) (actual time=330.943..330.951 rows=10 loops=1) > -> Index Scan Backward using main_table_pkey on main_table m (cost=0.00..36389.36 rows=5281 width=14) (actual time=330.937..330.940 rows=10 loops=1) > Filter: ((ord >= 5000) AND (ord <= 5500)) > Total runtime: 330.975 ms > > I havent found it on TODO or in archives so I'm wondering if this is a known behavior. > > Regards, > Rikard > Hi, Disregard the VIEW for the moment. (its not the issue here). I wasn't able to get much better than a LIMIT of around 50 after a SET STATISTICS 1000 on the PK column (i). julian=# explain analyse select * from main_table m where m.ord >= 5000 and m.ord <= 5500 order by m.i desc limit 49; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------ Limit (cost=352.73..352.85 rows=49 width=14) (actual time=3.215..3.227 rows=49 loops=1) -> Sort (cost=352.73..365.23 rows=5000 width=14) (actual time=3.213..3.217 rows=49 loops=1) Sort Key: i Sort Method: top-N heapsort Memory: 27kB -> Index Scan using ix_ord on main_table m (cost=0.00..187.36 rows=5000 width=14) (actual time=0.025..1.479 rows=5010 loops=1) Index Cond: ((ord >= 5000) AND (ord <= 5500)) Total runtime: 3.252 ms However, at LIMIT 48 it goes bad: julian=# explain analyse select * from main_table m where m.ord >= 5000 and m.ord <= 5500 order by m.i desc limit 48; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------------------------- Limit (cost=0.00..349.34 rows=48 width=14) (actual time=280.158..280.179 rows=48 loops=1) -> Index Scan Backward using main_table_pkey on main_table m (cost=0.00..36389.36 rows=5000 width=14) (actual time=280.156..280.172 rows=48 loops=1) Filter: ((ord >= 5000) AND (ord <= 5500)) Rows Removed by Filter: 944991 Total runtime: 280.206 ms 49 rows is pretty good IMO. But others might want to give some tips, because I don't use LIMIT much. You might want to consider using CURSORs - Which in this example would cache the 49 rows and pass the rows you limit (FETCH) more efficiently. Regards, Jules. -- Sent via pgsql-performance mailing list (pgsql-performance@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-performance