Received: from maia.hub.org (maia-2.hub.org [200.46.204.251]) by mail.postgresql.org (Postfix) with ESMTP id 6D22013364DE for ; Tue, 5 Apr 2011 20:03:13 -0300 (ADT) Received: from mail.postgresql.org ([200.46.204.86]) by maia.hub.org (mx1.hub.org [200.46.204.251]) (amavisd-maia, port 10024) with ESMTP id 77538-08 for ; Tue, 5 Apr 2011 23:02:54 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from mh7.mail.rice.edu (mh7.mail.rice.edu [128.42.199.46]) by mail.postgresql.org (Postfix) with ESMTP id E218F1337BCF for ; Tue, 5 Apr 2011 20:02:53 -0300 (ADT) Received: from mh7.mail.rice.edu (localhost.localdomain [127.0.0.1]) by mh7.mail.rice.edu (Postfix) with ESMTP id 49AE029007F; Tue, 5 Apr 2011 18:02:53 -0500 (CDT) X-Virus-Scanned: by amavis-2.6.4 at mh7.mail.rice.edu, auth channel Received: from mh7.mail.rice.edu ([127.0.0.1]) by mh7.mail.rice.edu (mh7.mail.rice.edu [127.0.0.1]) (amavis, port 10026) with ESMTP id o-ZoqPV8Qr1i; Tue, 5 Apr 2011 18:02:53 -0500 (CDT) X-SMTP-Auth: no X-SMTP-Auth: no Received: from aart.is.rice.edu (aart.is.rice.edu [168.7.56.48]) by mh7.mail.rice.edu (Postfix) with ESMTP id 1B48B290074; Tue, 5 Apr 2011 18:02:53 -0500 (CDT) Received: by aart.is.rice.edu (Postfix, from userid 18612) id 7EB072D5A6; Tue, 5 Apr 2011 18:02:52 -0500 (CDT) Date: Tue, 5 Apr 2011 18:02:51 -0500 From: Kenneth Marshall To: Thom Brown Cc: pgsql-performance Subject: Re: Partial index slower than regular index Message-ID: <20110405230251.GD26726@aart.is.rice.edu> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.16 (2007-06-09) X-Virus-Scanned: Maia Mailguard 1.0.1 X-Spam-Status: No, hits=-1.91 tagged_above=-10 required=5 tests=BAYES_00=-1.9, T_RP_MATCHES_RCVD=-0.01 X-Spam-Level: X-Archive-Number: 201104/34 X-Sequence-Number: 43096 On Tue, Apr 05, 2011 at 11:35:29PM +0100, Thom Brown wrote: > I'm using 9.1dev. > > Could someone explain the following behaviour? > > -- create a test table > CREATE TABLE indextest (id serial, stuff text); > > -- insert loads of values with intermittent sets of less common values > INSERT INTO indextest (stuff) SELECT 'meow' FROM generate_series (1,1000000); > INSERT INTO indextest (stuff) SELECT 'bark' FROM generate_series (1,1000); > INSERT INTO indextest (stuff) SELECT 'meow' FROM generate_series (1,1000000); > INSERT INTO indextest (stuff) SELECT 'bark' FROM generate_series (1,1000); > INSERT INTO indextest (stuff) SELECT 'meow' FROM generate_series (1,1000000); > INSERT INTO indextest (stuff) SELECT 'bark' FROM generate_series (1,1000); > INSERT INTO indextest (stuff) SELECT 'meow' FROM generate_series (1,1000000); > INSERT INTO indextest (stuff) SELECT 'bark' FROM generate_series (1,1000); > INSERT INTO indextest (stuff) SELECT 'meow' FROM generate_series (1,1000000); > INSERT INTO indextest (stuff) SELECT 'bark' FROM generate_series (1,1000); > INSERT INTO indextest (stuff) SELECT 'meow' FROM generate_series (1,1000000); > INSERT INTO indextest (stuff) SELECT 'bark' FROM generate_series (1,1000); > INSERT INTO indextest (stuff) SELECT 'meow' FROM generate_series (1,1000000); > INSERT INTO indextest (stuff) SELECT 'bark' FROM generate_series (1,1000); > INSERT INTO indextest (stuff) SELECT 'meow' FROM generate_series (1,1000000); > INSERT INTO indextest (stuff) SELECT 'bark' FROM generate_series (1,1000); > > -- create regular index > CREATE INDEX indextest_stuff ON indextest(stuff); > > -- update table stats > ANALYZE indextest; > > postgres=# explain analyze select * from indextest where stuff = 'bark'; > QUERY PLAN > ----------------------------------------------------------------------------------------------------------------------------------- > Index Scan using indextest_stuff on indextest (cost=0.00..485.09 > rows=9076 width=9) (actual time=0.142..3.533 rows=8000 loops=1) > Index Cond: (stuff = 'bark'::text) > Total runtime: 4.248 ms > (3 rows) > > This is very fast. Now if I drop the index and add a partial index > with the conditions being tested. > > DROP INDEX indextest_stuff; > > CREATE INDEX indextest_stuff ON indextest(stuff) WHERE stuff = 'bark'; > > postgres=# explain analyze select * from indextest where stuff = 'bark'; > QUERY PLAN > ------------------------------------------------------------------------------------------------------------------- > Seq Scan on indextest (cost=0.00..143386.48 rows=5606 width=9) > (actual time=164.321..1299.794 rows=8000 loops=1) > Filter: (stuff = 'bark'::text) > Total runtime: 1300.267 ms > (3 rows) > > The index doesn't get used. There's probably a logical explanation, > which is what I'm curious about. > The stats seem off. Are you certain that an analyze has run? Cheers, Ken