Received: from localhost (maia-3.hub.org [200.46.204.184]) by postgresql.org (Postfix) with ESMTP id AE6479FB619 for ; Thu, 7 Jun 2007 22:12:45 -0300 (ADT) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.184]) (amavisd-maia, port 10024) with ESMTP id 84369-01 for ; Thu, 7 Jun 2007 22:12:33 -0300 (ADT) X-Greylist: from auto-whitelisted by SQLgrey-1.7.5 Received: from sss.pgh.pa.us (sss.pgh.pa.us [66.207.139.130]) by postgresql.org (Postfix) with ESMTP id BFE2E9FBFF8 for ; Thu, 7 Jun 2007 22:12:41 -0300 (ADT) Received: from sss2.sss.pgh.pa.us (tgl@localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.1/8.14.1) with ESMTP id l581BJ9O011350; Thu, 7 Jun 2007 21:11:20 -0400 (EDT) To: "Steven Flatt" cc: "Steinar H. Gunderson" , pgsql-performance@postgresql.org Subject: Re: performance drop on 8.2.4, reverting to 8.1.4 In-reply-to: <357fa7590706071011g4e337937rc622ffed39856425@mail.gmail.com> References: <20070518104646.GA13811@uio.no> <008201c7993c$76c88a10$653e10ac@ilgvaio> <20070518111455.GA13978@uio.no> <28604.1179503689@sss.pgh.pa.us> <357fa7590706051430h5db6760dx9d4a46c7a8a36205@mail.gmail.com> <10645.1181081285@sss.pgh.pa.us> <357fa7590706071011g4e337937rc622ffed39856425@mail.gmail.com> Comments: In-reply-to "Steven Flatt" message dated "Thu, 07 Jun 2007 13:11:44 -0400" Date: Thu, 07 Jun 2007 21:11:19 -0400 Message-ID: <11349.1181265079@sss.pgh.pa.us> From: Tom Lane X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200706/146 X-Sequence-Number: 25179 "Steven Flatt" writes: > One instance of our problem goes like this, and I have included a > self-contained example with which you can reproduce the problem. This is fairly interesting, because if you run the query by hand after the function finishes, it's pretty fast. What I think is happening is that the plpgsql function caches a plan for the catalog query that is predicated on pg_constraint and pg_inherits being small, and after you've inserted a few thousand rows in them, that's not true anymore. In CVS 8.2 (and HEAD), the core of the query seems to be planned like this initially: -> Hash Join (cost=1.24..8.70 rows=1 width=76) Hash Cond: (c.conrelid = i.inhparent) -> Seq Scan on pg_constraint c (cost=0.00..7.35 rows=27 width=76) Filter: (confrelid <> 0::oid) -> Hash (cost=1.23..1.23 rows=1 width=8) -> Seq Scan on pg_inherits i (cost=0.00..1.23 rows=1 width=8) Filter: (inhrelid = 42154::oid) With a thousand or so rows inserted in each catalog, it likes this plan better: -> Nested Loop (cost=0.00..16.55 rows=1 width=76) -> Index Scan using pg_inherits_relid_seqno_index on pg_inherits i (cost=0.00..8.27 rows=1 width=8) Index Cond: (inhrelid = 42154::oid) -> Index Scan using pg_constraint_conrelid_index on pg_constraint c (cost=0.00..8.27 rows=1 width=76) Index Cond: (c.conrelid = i.inhparent) Filter: (c.confrelid <> 0::oid) and indeed that plan is a lot better as the catalogs grow. But the plpgsql function cached the other plan at start. I'm not entirely sure why 8.1 doesn't fall into the same trap --- perhaps it's because it's unable to rearrange outer joins. It's certainly not being any smarter than 8.2. Anyway, it seems that you could either try to get some pg_constraint and pg_inherits rows created before you start this function, or you could change it to use an EXECUTE to force replanning of the inner query. Or just start a new session after the first few hundred table creations. I was hoping that the auto plan invalidation code in CVS HEAD would get it out of this problem, but it seems not to for the problem-as-given. The trouble is that it won't change plans until autovacuum analyzes the tables, and that won't happen until the transaction commits and sends off its I-inserted-lotsa-rows report to the stats collector. So any given large transaction is stuck with the plans it first forms. There's probably nothing we can do about that in time for 8.3, but it's something to think about for future releases ... regards, tom lane