Subject | Re: Ignoring a FK index |
---|---|
Author | Svein Erling Tysvær |
Post date | 2006-02-02T08:20:40Z |
Hi Adam!
Replying to both posts:
this part of the index anyway and if it does, then I'd say PK_TABLEB
is to be preferred.
not see yet.
SELECT <whatever>
FROM TableB B
JOIN TableA A ON A.ID = B.TableAID
WHERE B.TableAID = :Param
may possibly use the plan you report, whereas
SELECT <whatever>
FROM TableB B
JOIN TableA A ON A.ID = B.TableAID
WHERE B.TableAID = :Param
AND B.ID = :Param2
would be better off with
PLAN JOIN (B INDEX (PK_TABLEB),A INDEX (PK_TABLEA))
In neither case do I believe the TEST index to be of any help. Please
show some SQL so that I get a better understanding of your problem and
a case where the TEST index is useful (I can understand the value of
adding the PK to an index when it comes to deletes, but not yet for
selects). Is it something like:
SELECT <whatever>
FROM TableB B
JOIN TableA A ON A.ID = B.TableAID
WHERE B.TableAID = :Param
AND B.ID BETWEEN :Param2 AND :Param3
If so, I may be able to understand the TEST index, though if so, I'm
surprised that the optimizer doesn't suggest it...
containing only breast cancer. An index on gender would be useless
when looking for women, whereas it would be very good if looking for
men (breast cancer is far more common amongst women than amongst men).
Hmm, now I'm curious, tell us more,
Set
Replying to both posts:
> After receiving some complaints at a particular site about slowness,Three brilliant reasons.
> I decided to investigate and found that they have a foreign key
> index with terrible selectivity.
>
> Now I have tried a couple of things to improve performance.
> Obviously by adding +0 in my joins and where clause where this field
> is referenced, the speed problem is reduced, although it could
> certainly do better if it had an index with good selectivity.
>
> The structure looks something like this:
>
> tableA
> (
> ID,
> stuff
> )
>
> tableB
> (
> ID,
> tableAID,
> stuff
> )
>
> TableAID is a foreign key with terrible selectivity (for this
> customer only 5 unique values for 90000 records).
>
> Dropping the FK constraint is not an option because there is no way
> of implementing a pseudo FK constraint using for example the CHECK
> clause or triggers as this is not safe (isolation rules). It will
> also confuse the reverse engineering tools we use from time to time,
> and does go against the relational model (IMO).
> I added the following index in an attempt to help the optimiserWhy? If your WHERE clause doesn't include TABLEB.ID, it cannot use
>
> CREATE INDEX TEST ON TABLEB (TABLEAID, ID);
>
> however it is ignored. The index has a selectivity of 1, so I think
> it should be favoured over another index with selectivity > 12000.
this part of the index anyway and if it does, then I'd say PK_TABLEB
is to be preferred.
> But instead, the optimiser electsSo far, I agree with the optimizer! But maybe there's something I do
>
> PLAN JOIN (TABLEB INDEX (FK_TABLEBTABLEAID),TABLEA INDEX
> (PK_TABLEA))
>
> If I manually specify the plan
>
> PLAN JOIN (TABLEB INDEX (TEST),TABLEA INDEX (PK_TABLEA))
>
> it works very quickly. Is there anyway to suggest to the optimiser
> that it should use the TEST index rather than the poor selectivity
> foreign key, or do I have to put up with a table scan until the
> optimiser is smartened up a bit more.
not see yet.
> Even without the hint directive, can you think of any reason youWell, I've not yet seen your SQL. A statement like
> would ever want to use a FK index with poor selectivity where a
> compound key starting with the FK field with perfect selectivity
> exists?
SELECT <whatever>
FROM TableB B
JOIN TableA A ON A.ID = B.TableAID
WHERE B.TableAID = :Param
may possibly use the plan you report, whereas
SELECT <whatever>
FROM TableB B
JOIN TableA A ON A.ID = B.TableAID
WHERE B.TableAID = :Param
AND B.ID = :Param2
would be better off with
PLAN JOIN (B INDEX (PK_TABLEB),A INDEX (PK_TABLEA))
In neither case do I believe the TEST index to be of any help. Please
show some SQL so that I get a better understanding of your problem and
a case where the TEST index is useful (I can understand the value of
adding the PK to an index when it comes to deletes, but not yet for
selects). Is it something like:
SELECT <whatever>
FROM TableB B
JOIN TableA A ON A.ID = B.TableAID
WHERE B.TableAID = :Param
AND B.ID BETWEEN :Param2 AND :Param3
If so, I may be able to understand the TEST index, though if so, I'm
surprised that the optimizer doesn't suggest it...
> Perhaps it is as simple as an improvement to the optimiser to ignoreYou forget the case of unbalanced indexes. Suppose a cancer registry
> any index with a selectivity worse than ____ [insert value]. Then
> again, perhaps this is easier said then done.
containing only breast cancer. An index on gender would be useless
when looking for women, whereas it would be very good if looking for
men (breast cancer is far more common amongst women than amongst men).
Hmm, now I'm curious, tell us more,
Set