Received: from maia.hub.org (maia-5.hub.org [200.46.204.29]) by mail.postgresql.org (Postfix) with ESMTP id C286EB5DBC2 for ; Mon, 20 Jun 2011 11:07:00 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.29]) (amavisd-maia, port 10024) with ESMTP id 41158-05 for ; Mon, 20 Jun 2011 14:06:54 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from outmail149112.authsmtp.co.uk (outmail149112.authsmtp.co.uk [62.13.149.112]) by mail.postgresql.org (Postfix) with ESMTP id 17BE9B5D90E for ; Mon, 20 Jun 2011 11:06:53 -0300 (ADT) Received: from mail-c187.authsmtp.com (mail-c187.authsmtp.com [62.13.128.33]) by punt12.authsmtp.com (8.14.2/8.14.2/Kp) with ESMTP id p5KE6rMx016719 for ; Mon, 20 Jun 2011 15:06:53 +0100 (BST) Received: from mail-qy0-f181.google.com (mail-qy0-f181.google.com [209.85.216.181]) (authenticated bits=0) by mail.authsmtp.com (8.14.2/8.14.2) with ESMTP id p5KE6mek020907 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=FAIL) for ; Mon, 20 Jun 2011 15:06:49 +0100 (BST) Received: by qyk9 with SMTP id 9so1118431qyk.19 for ; Mon, 20 Jun 2011 07:06:48 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.88.198 with SMTP id b6mr3970495qcm.208.1308578808605; Mon, 20 Jun 2011 07:06:48 -0700 (PDT) Received: by 10.229.32.197 with HTTP; Mon, 20 Jun 2011 07:06:48 -0700 (PDT) In-Reply-To: <4DFF52BB.5060605@hbs-research.com> References: <4DC17AAB.1080206@hbs-research.com> <4DFF52BB.5060605@hbs-research.com> Date: Mon, 20 Jun 2011 15:06:48 +0100 Message-ID: Subject: Re: Prepared statments: partial indexes are avoided! From: Simon Riggs To: adrien ducos Cc: "pgsql-admin@postgresql.org" Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Server-Quench: 8abc15d1-9b46-11e0-ab46-001185d377ca X-AuthReport-Spam: If SPAM / abuse - report it at: http://www.authsmtp.com/abuse X-AuthRoute: OCdxZQATClZOTQEd DAteCiN5VAwpPBRK HVkIKg5MOFUSTAAU O0pfL1x7KFoHWV5D ViVKB0oLEgo/W2Nq EU8PcgddY0teXgBg UE5DRlscFgVhHxQE GBwfVAdzfwRZfXZ3 ekcsHnUgKUInIB19 QE5dFWpIYmJjbC4X ARILdgYAcR5DLBtD d1F+AXMQMDcDYGdg R1Zqb209ZmoAIy1D eAxfZWE7bWMqOAt0 fwoPBTw1EEFNXDk6 MxkrLEIHTg4JO18u MFIlEVMePxICBxYW FltASCZHIFgNSiZi ZU8N X-Authentic-SMTP: 61633235383639.1000:706 X-AuthFastPath: 0 (Was 255) X-AuthVirus-Status: No virus detected - but ensure you scan with your own anti-virus system. X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.9 tagged_above=-10 required=5 tests=BAYES_00=-1.9 X-Spam-Level: X-Archive-Number: 201106/121 X-Sequence-Number: 37747 On Mon, Jun 20, 2011 at 3:01 PM, adrien ducos wro= te: > I have postgres 8.4 > > I have a table "foo" with 16 million lines 99% of those lines have a colu= mn > "bar" =3D 1. > > I had an index on this table: > CREATE INDEX index_foo_bar ON foo using btree (bar); > > The thing is that the query > select count(*) from foo where bar =3D 1; > is not using the query (it is useless that is normal, using this index wo= uld > be slower than not using it) > > the query > select count(*) from foo where bar =3D 2; uses the index I have the answe= r in > 20ms. > > With a prepared statement I have > > PREPARE fooplan (int) AS > =A0 select count(*) from foo where bar =3D $1; > execute fooplan (2); > > also a few milliseconds > > Now in order to optimise this last request I droped the first index and > added a new index: > > CREATE INDEX index_foo_bar ON foo using btree (bar) where > created_by_user_group <> 1; > > since the query is only using the index in this case anyway. > > with the query > explain analyze select count(*) from foo where bar =3D 2; it uses the new > index : > > "Aggregate =A0(cost=3D8.29..8.30 rows=3D1 width=3D0) (actual time=3D0.119= ..0.119 > rows=3D1 loops=3D1)" > " =A0-> =A0Index Scan using index_foo_bar on foo =A0(cost=3D0.00..8.29 ro= ws=3D1 > width=3D0) (actual time=3D0.017..0.084 rows=3D63 loops=3D1)" > " =A0 =A0 =A0 =A0Index Cond: (bar =3D 2)" > "Total runtime: 0.144 ms" > > so great improvement from 20ms to 0.144ms > > and with the prepared statement... things becomes very bad: > PREPARE fooplan (int) AS > =A0 select count(*) from foo where bar =3D $1; > explain analyze execute fooplan (2); > > > "Aggregate =A0(cost=3D627406.08..627406.09 rows=3D1 width=3D0) (actual > time=3D11627.315..11627.316 rows=3D1 loops=3D1)" > " =A0-> =A0Seq Scan on foo =A0(cost=3D0.00..603856.80 rows=3D9419712 widt= h=3D0) (actual > time=3D7070.334..11627.266 rows=3D63 loops=3D1)" > " =A0 =A0 =A0 =A0Filter: (bar =3D $1)" > "Total runtime: 11627.357 ms" > > No index uses and the time becomes very bad. > > This is probably due to the fact the prepared statement could have "1" as= an > input and so it avoids the index completely, but this is not very nice fo= r > software optimization since I am using pdo which uses prepared statements > all the time and is unable to use all the partial indexes. > > The problem is I have 90 GB of indexes in the database and partial indexe= s > could help me to save some of this space on my server, in addition to > improve the speed of the queries. Unfortunately, prepared statements do act in the way you have seen. I have a patch into 9.2 under discussion to improve upon this situation, but don't hold your breath for that. --=20 =A0Simon Riggs=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 http:/= /www.2ndQuadrant.com/ =A0PostgreSQL Development, 24x7 Support, Training & Services