Search Postgresql Archives

Re: Planner chooses multi-column index in 9.2 when maybe it should not

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Greg Sabino Mullane <greg@xxxxxxxxxxxx> writes:
> We are seeing a performance regression when moving to 9.2. There is a 
> complex query that is doing a self-join, but long story short, it 
> is choosing to use a multi-column index when it really ought not to be.
> I was not able to develop a standalone test case without resorting 
> to changing enable_seqscan, but this does show the difference:

> CREATE TABLE gregtest (a TEXT PRIMARY KEY, b TEXT);
> CREATE INDEX gregtest_i ON gregtest(b,a);
> SET enable_seqscan = off;
> EXPLAIN SELECT 1 FROM gregtest WHERE a <> 'panda' AND b <> 'yak';

> On versions 8.2, 8.3, 8.4, 9.0, and 9.1, this gives:

>  Seq Scan on gregtest  (cost=10000000000.00..10000000022.90 rows=855 width=0)
>    Filter: ((a <> 'panda'::text) AND (b <> 'yak'::text))

> Which makes sense - I would imagine that b = 'yak' would use the index, 
> but the negation means the index is not very useful?

> However, on 9.2, this gives:

>  Bitmap Heap Scan on gregtest  (cost=8.76..31.66 rows=855 width=0)
>    Filter: ((a <> 'panda'::text) AND (b <> 'yak'::text))
>    ->  Bitmap Index Scan on gregtest_i  (cost=0.00..8.55 rows=860 width=0)

The above doesn't seem like a regression to me.  You told it not to use
a seqscan, and it didn't.  (The reason it now considers the index is
that an index-only scan is possible; before 9.2 there was no reason to
consider an indexscan at all given this query, so you got the seqscan
despite the attempted disable.)


> The above was tested on stock versions of Postgres, with no changes 
> made to postgresql.conf. In the actual query, the result is something like 
> this on 9.2 (columns explained below):

>  Nested Loop  (cost=0.00..6050226723847.12 rows=282638194054762 width=8)
>    Join Filter: ((o.foo)::text <> ((m.foo)::text || 'panda'::text))
>    ->  Index Only Scan using index_i on foobar m  (cost=0.00..889187.83 rows=16998032 width=8)
>    ->  Materialize  (cost=0.00..1079773.42 rows=16627702 width=8)
>          ->  Index Only Scan using index_i on foobar o  (cost=0.00..931682.91 rows=16627702 width=8)
>                Filter: ((status)::text <> 'split'::text)

It's not obvious that this is a worse plan than a seqscan --- the
index-only scans will only have to read the index not the heap, at least
if the heap is all-visible.  If it's coming out slower, then that's a
question of whether the cost estimates match reality.  I'd wonder how
many heap fetches occur anyway, and also whether you've tweaked the
planner cost parameters.

You should be able to force it back to the seqscan based plan by turning
off enable_indexscan or enable_indexonlyscan.  It would be useful to
see EXPLAIN ANALYZE (not just EXPLAIN) results for both this plan and
the seqscan plan in 9.2.

			regards, tom lane


-- 
Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux