Re: Strange (?) Index behavior?

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

 



On Fri, 05 Nov 2004 16:08:56 -0500, Tom Lane <tgl@xxxxxxxxxxxxx> wrote:


> Allen Landsidel <alandsidel@xxxxxxxxx> writes:
> > With seqscan enabled however, "AB%" will use the index, but "A%" will not.
>
> > The estimated cost for the query is much higher without the partial
> > indexes than it is with them, and the actual runtime of the query is
> > definitely longer without the partial indexes.
>
> OK.  This suggests that the planner is drastically misestimating
> the selectivity of the 'A%' clause, which seems odd to me since in
> principle it could get that fairly well from the ANALYZE histogram.
> But it could well be that you need to increase the resolution of the
> histogram --- see ALTER TABLE SET STATISTICS.

I will look into this.

>
> Did you ever show us EXPLAIN ANALYZE results for this query?

No, I didn't.  I am running it now without the partial index on to
give you the results but it's (the 'A%' problem query) been running
pretty much since I got this message (an hour ago) and is still not
finished.

The EXPLAIN results without the ANALYZE will have to suffice until
it's done, I can readd the index, and run it again, so you have both
to compare to.

First two queries run where both the main index, and the 'A%' index exist:

-- QUERY 1
search=# explain
search-# SELECT test_name FROM test WHERE test_name LIKE 'A%';
                                       QUERY PLAN
-------------------------------------------------------------------------------------------
Index Scan using test_name_idx_a on "test"  (cost=0.00..8605.88
rows=391208 width=20)
  Index Cond: ((test_name >= 'A'::text) AND (test_name < 'B'::text))
  Filter: (test_name ~~ 'A%'::text)
(3 rows)

Time: 16.507 ms

-- QUERY 2
search=# explain
search-# SELECT test_name FROM test WHERE test_name LIKE 'A%' AND
test_name LIKE 'AB%';
                                                              QUERY
PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
Index Scan using test_name_idx_a on "test"  (cost=0.00..113.79
rows=28 width=20)
  Index Cond: ((test_name >= 'A'::text) AND (test_name < 'B'::text)
AND (test_name >= 'AB'::text) AND (test_name < 'AC'::text))
  Filter: ((test_name ~~ 'A%'::text) AND (test_name ~~ 'AB%'::text))
(3 rows)

Time: 3.197 ms

Ok, now the same two queries after a DROP INDEX test_name_idx_a;

search=# explain
search-# SELECT test_name FROM test WHERE test_name LIKE 'A%';
                                         QUERY PLAN
-----------------------------------------------------------------------------------------------
Index Scan using test_name_unique on "test"  (cost=0.00..1568918.66
rows=391208 width=20)
  Index Cond: ((test_name >= 'A'::text) AND (test_name < 'B'::text))
  Filter: (test_name ~~ 'A%'::text)
(3 rows)

Time: 2.470 ms

search=# explain
search-# SELECT test_name FROM test WHERE test_name LIKE 'AB%';
                                       QUERY PLAN
-------------------------------------------------------------------------------------------
Index Scan using test_name_unique on "test"  (cost=0.00..20379.49
rows=5081 width=20)
  Index Cond: ((test_name >= 'AB'::text) AND (test_name < 'AC'::text))
  Filter: (test_name ~~ 'AB%'::text)
(3 rows)

Time: 2.489 ms

------------------
Copying just the costs you can see the vast difference...
Index Scan using test_name_unique on "test"  (cost=0.00..1568918.66
rows=391208 width=20)
Index Scan using test_name_unique on "test"  (cost=0.00..20379.49
rows=5081 width=20)

vs

Index Scan using test_name_idx_a on "test"  (cost=0.00..8605.88
rows=391208 width=20)
Index Scan using test_name_idx_a on "test"  (cost=0.00..113.79
rows=28 width=20)

Lastly no, neither of these row guesstimates is correct..  I'll get
back and tell you how much they're off by if it's important, once this
query is done.

The odd thing is it used the index scan here each time -- that has not
always been the case with the main unique index, it's trying to make a
liar out of me heh.

I'm used to the estimates and plan changing from one vacuum analyze to
the next, even without any inserts or updates between.. the index scan
is always used however when I have the partial indexes in place, and
something like..

CREATE TEMP TABLE t1 AS
 SELECT field FROM table
 WHERE field LIKE 'A%'
 AND field LIKE 'AA%';

runs in 6-8 seconds as well, with a bit under 100k records.

-Allen


[Postgresql General]     [Postgresql PHP]     [PHP Users]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Yosemite]

  Powered by Linux