From: | Howie <caffeine(at)toodarkpark(dot)org> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | pgsql-sql(at)postgreSQL(dot)org |
Subject: | Re: [SQL] optimizer not using an index... |
Date: | 1999-08-27 17:01:59 |
Message-ID: | Pine.LNX.3.96.990827161640.7463G-100000@rabies.toodarkpark.org |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-sql |
On Fri, 27 Aug 1999, Tom Lane wrote:
> Howie <caffeine(at)toodarkpark(dot)org> writes:
> > explain reveals that postgres ( 6.5.0 ) isnt using some of my indexes,
> > opting instead for a complete table scan ( and drastically slowing things
> > down ).
>
> Well, mumble. The optimizer certainly needs work, but what's your
> evidence that this query would be faster if done another way? Hashing
> the smaller tables, as it's doing, ought to be a pretty good strategy.
primary focus was on why pgsql decided to do a complete table scan of
customers ( searching for customer.email ) when there's an index on it;
surely an index scan would be loads faster than a complete table scan.
the other interesting item i ran into was why one query used the indexes
provided and the other didnt. granted, pincodes has at least 10x more
entries than customers does ( ~300k+ vs ~11k ).
> One way to check is to start your client with environment variable
> setting PGOPTIONS="-fh" ("forbid hashjoin") to discourage the optimizer
> from using hashes, then check the generated plan for the same query and
> see what its actual runtime is. That's likely to be a suboptimal plan
> however, since it'll turn off *all* hashing. The hash on customers is
> probably the thing that's bothering you.
that and pgsql not using the indexes that the query on pincodes.code does.
using -fh causes pgsql to use all the proper indexes, but still beefs up 4
merge joins, seq scans, sorts, and nested loops:
[excerpt]
Merge Join (cost=355979.91 rows=293465 width=222)
-> Seq Scan (cost=342501.81 rows=376206 width=138)
-> Sort (cost=342501.81 rows=376206 width=138)
-> Nested Loop (cost=20616.32 rows=376206 width=138)
-> Merge Join (cost=76.34 rows=413 width=118)
-> Merge Join (cost=33.01 rows=87 width=60)
-> Merge Join (cost=20.28 rows=81 width=56)
( query on customers.email )
> How many result rows do you actually get from this query?
when querying on pincodes.code, i get 1 row back. when querying on
customers.email, i get 4 rows back. it's producing the correct results,
its just going about getting those results in a somewhat odd manner.
> If you eliminate the customers table from the query, and just do the
> same join among the remaining tables, how many rows do you get?
1, as expected.
Hash Join (cost=21.73 rows=5 width=138)
-> Seq Scan on ibill (cost=3.64 rows=80 width=28)
-> Hash (cost=14.32 rows=4 width=110)
-> Nested Loop (cost=14.32 rows=4 width=110)
-> Nested Loop (cost=8.17 rows=3 width=106)
-> Nested Loop (cost=4.07 rows=2 width=78)
-> Index Scan using codes_code_idx on pincodes (cost=2.02 rows=1 width=20)
-> Index Scan using types_pkey on subaccts (cost=2.05 rows=379 width=58)
-> Index Scan using doms_pkey on domains (cost=2.05 rows=80 width=28)
-> Index Scan using owner_client_idx on owners (cost=2.05 rows=85 width=4)
> I suspect the optimizer is drastically off in its estimate of ~300k
> result rows, and that's contributing to the problem.
yes, so why is it off for one query but right on target for the other ?
more importantly, why is it chosing to use indexes for one query yet
chosing to do complete table scans for the other ( even though the two
queries are almost identical ) ?
answer that and i'll personally treat you to a beer. :)
> > doing a complete table scan on a column thats indexed isnt really that
> > nice, especially since there are 12,000 entries in it.
>
> But it's estimating it's going to have to probe that table 300k times,
> which makes the hashjoin look mighty attractive...
why would it have to probe pincodes 300k times when there's a unique index
on pincodes ( pincodes.codenum ) and a unique index on customers (
customers.codenum ) ?
> > interestingly, when querying on "pincodes.code" instead of
> > "customers.name", postgres does NOT use a full table scan; it uses the
> > proper indexes:
>
> > Hash Join (cost=23.78 rows=5 width=222)
>
> Note the drastic difference in the estimated result-row count; that's
> undoubtedly what's changing the optimizer's choice of what to do. You
> haven't given us enough detail to understand why this query would be
> (or at least seem) more selective than the other, however.
im not sure it would; i placed indexes in ( what i thought were ) all the
proper places - pincodes.code, pincodes.codenum, customers.name,
customers.codenum... every column that's being queried on or joined on.
ideally, all the indexes would be used and querying on customers.email
would be ( query-plan wise ) almost identical to querying on
pincodes.code; only an index would change.
> Anyway, this looks to me like it is probably a symptom of poor
> selectivity estimation leading to bogus estimates of output row counts
> leading to a nonoptimal plan choice. I have been working on improving
> the selectivity estimation for 6.6, and am looking for test cases to
> check out the logic on. Is your database small enough/non proprietary
> enough that you could send me a dump?
i could send you a dump, but the db is fairly large; 7m uncompressed, 2m
gzip -9'ed. none of the data is overly sensetive. i am, however, on an
overly lagged 28k8.
> Or could you strip it down to
> a test case that still exhibits the same misbehavior?
i havent tried trimming the db down. im not sure that would 'fix' the
problem if the optimizer is misguessing the number of rows it's going to
have to look at...
> If you don't
> like either of those, perhaps you could grab a current snapshot, install
> your data in a test postmaster, and report back on whether it acts any
> different...
over the weekend im planning on upgrading to 6.5.1, but i dont recall
seeing any changes to the optimizer in the changelog...
---
Howie <caffeine(at)toodarkpark(dot)org> URL: http://www.toodarkpark.org
"The distance between insanity and genius is measured only by success."
From | Date | Subject | |
---|---|---|---|
Next Message | Thomas Good | 1999-08-27 17:03:34 | Re: [SQL] vacuum fails |
Previous Message | Tom Lane | 1999-08-27 16:52:07 | Re: [SQL] optimizer not using an index... |