Received: from localhost (unknown [200.46.204.184]) by postgresql.org (Postfix) with ESMTP id 486202E003C for ; Tue, 19 Feb 2008 06:58:53 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.184]) (amavisd-maia, port 10024) with ESMTP id 66041-08 for ; Tue, 19 Feb 2008 06:58:37 -0400 (AST) Received: from cat.co.za (mailer.cat.co.za [196.34.125.51]) by postgresql.org (Postfix) with SMTP id 332512E0030 for ; Tue, 19 Feb 2008 06:58:37 -0400 (AST) Received: (qmail 21061 invoked by uid 1002); 19 Feb 2008 11:06:17 -0000 Received: from stuartb@cat.co.za by mail.cat.co.za by uid 807 with qmail-scanner-1.21 (clamscan: 0.70. Clear:RC:1(196.34.125.52):. Processed in 3.807629 secs); 19 Feb 2008 11:06:17 -0000 Received: from unknown (HELO ?192.168.34.201?) (196.34.125.52) by 0 with SMTP; 19 Feb 2008 11:06:12 -0000 Message-ID: <47BAB556.7060506@cat.co.za> Date: Tue, 19 Feb 2008 12:54:14 +0200 From: Stuart Brooks User-Agent: Thunderbird 2.0.0.9 (Windows/20071031) MIME-Version: 1.0 To: pgsql-sql@postgresql.org Subject: Am I wasting my time with partitions? Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=0.174 tagged_above=0 required=5 tests=AWL=-0.235, SUBJECT_FUZZY_TION=0.41 X-Spam-Level: X-Archive-Number: 200802/148 X-Sequence-Number: 30239 It seems to me that postgresql doesn't use indexes when being asked for an ordered result sets from a partitioned table. I have an application where this is critical, but I was hoping to use partitions because of the ease of rotating out old rows. Simply put, I have a table called LineItems which I need to be able to page from and so I need to be able to ask for N rows ordered on a certain index (with possible constraints). eg. SELECT * FROM T ORDER BY col1,col2 LIMIT 10; This works fine and is quick on a single table: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> metadb=> \d lineitems Table "test2.lineitems" Column | Type | Modifiers --------------+--------------------------------+----------- lineitem_key | bigint | not null time | timestamp(6) without time zone | not null description | text | not null barcode | text | not null amount | bigint | not null Indexes: "lineitems_amount_index" btree (amount, lineitem_key) metadb=> explain select * from lineitems order by amount,lineitem_key limit 10; QUERY PLAN -------------------------------------------------------------------------------------------------------- Limit (cost=0.00..0.74 rows=10 width=49) -> Index Scan using lineitems_amount_index on lineitems (cost=0.00..39791.76 rows=535500 width=49) (2 rows) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> If I partition the table by creating a top level table L, and inherited tables L1, L2 and issue the same request it does sequential scans on all the tables and takes orders of magnitude longer (see below). In the example below I would have hoped that it would have used an index scan on each of the tables returning 10 rows each and then done a merge on them. Am I asking too much? Should I just use a single table and take the hits on deletes and vacuums? Regards Stuart >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> metadb=> \d L Table "test2.l" Column | Type | Modifiers --------------+--------------------------------+----------- lineitem_key | bigint | not null time | timestamp(6) without time zone | not null description | text | not null barcode | text | not null amount | bigint | not null Indexes: "l_amount_index" btree (amount, lineitem_key) metadb=> \d L1 Table "test2.l1" Column | Type | Modifiers --------------+--------------------------------+----------- lineitem_key | bigint | not null time | timestamp(6) without time zone | not null description | text | not null barcode | text | not null amount | bigint | not null Indexes: "l1_amount_index" btree (amount, lineitem_key) Inherits: l metadb=> \d L2 Table "test2.l2" Column | Type | Modifiers --------------+--------------------------------+----------- lineitem_key | bigint | not null time | timestamp(6) without time zone | not null description | text | not null barcode | text | not null amount | bigint | not null Indexes: "l2_amount_index" btree (amount, lineitem_key) Inherits: l metadb=> explain select * from l order by amount,lineitem_key limit 10; QUERY PLAN ------------------------------------------------------------------------------------- Limit (cost=22207.70..22207.72 rows=10 width=88) -> Sort (cost=22207.70..23548.09 rows=536156 width=88) Sort Key: test2.l.amount, test2.l.lineitem_key -> Result (cost=0.00..10621.56 rows=536156 width=88) -> Append (cost=0.00..10621.56 rows=536156 width=88) -> Seq Scan on l (cost=0.00..16.90 rows=690 width=88) -> Seq Scan on l1 l (cost=0.00..4951.00 rows=250000 width=49) -> Seq Scan on l2 l (cost=0.00..5653.66 rows=285466 width=49) (8 rows) NB. Just addressing one of the inherited tables works fine. metadb=> explain select * from l1 order by amount,lineitem_key limit 10; QUERY PLAN ------------------------------------------------------------------------------------------ Limit (cost=0.00..0.74 rows=10 width=49) -> Index Scan using l1_amount_index on l1 (cost=0.00..18554.20 rows=250000 width=49) (2 rows) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>