Subject | Re: [firebird-support] Re: FB2 Refuses to use index in multi table join |
---|---|
Author | Alexandre Benson Smith |
Post date | 2008-11-25T05:30:38Z |
David,
dkeith2 wrote:
I think the index used is the PK/FK index
index base on field NDC9, acording to you plan the index used is
IDX_NDCLISTINGS_NDC9, that I think is based on field NDC9 not on field
TradeName.
If you used a like clause as I said on the prior message, probably the
plan would be something like:
Indexed Read on Table L using index on Field TradeName to filter out the
records, then
read Table R using the FK/PK index (NDC9), then
read Table F using the FK/PK index (NDC9), then
read Table B using the FK.PK index (CPNUM) and then
sort it all in memory to remove the duplicates
(The order of R, F and B could differ, but should not matter for the
example I gave)
This way you will have a fully indexed search
The example you provided could not use an index to filter out the
records, so at least one table would need to be scan naturally, FB
chooses the smaller one.
will use an index:
where L.TradeName = 'Something'
where L.TradeName starts with 'Something'
where L.TradeName like 'Something%'
will not use an index
where L.TradeName <> 'Something'
where L.TradeName containing 'Something'
where L.TradeName like '%Something%'
your plan
PLAN
SORT (
JOIN (R NATURAL,
F INDEX (IDX_CP_FDA_MAP_NDC9),
B INDEX (IDX_CPNUM_CPNUM),
L INDEX (IDX_NDCLISTINGS_NDC9)
)
)
says:
Read table R from the first record to the end in the storage order, then:
read the record from table F using index IDX_CP_FDA_MAP_NDC9 to match
the clause (F.NDC9 = R.NDC9), then
read the record from table B using index IDX_CPNUM_CPNUM to match the
clause (B.CPNUM = F.CPNUM), then
read the record from table L using index IDX_NDCLISTINGS_NDC9 to match
the clause (L.NDC9 = R.NDC9), then
filter out the results where L.TRADENAME LIKE '%'||UPPER('aceta')||'%'
and then
sort out the result set in memory to remove all the duplicates
see you !
--
Alexandre Benson Smith
Development
THOR Software e Comercial Ltda
Santo Andre - Sao Paulo - Brazil
www.thorsoftware.com.br
dkeith2 wrote:
> Alexandre -I dont think so... no index could be used for a LIKE '%foo%' expression,
>
> Thanks for your reply. L.TRADENAME does have a good index on it and
> the index is used
I think the index used is the PK/FK index
> , as that table shows -0- non-indexed reads and 6572It used an index not necessarily the index on TradeName, it used the
> indexed reads.
>
index base on field NDC9, acording to you plan the index used is
IDX_NDCLISTINGS_NDC9, that I think is based on field NDC9 not on field
TradeName.
If you used a like clause as I said on the prior message, probably the
plan would be something like:
Indexed Read on Table L using index on Field TradeName to filter out the
records, then
read Table R using the FK/PK index (NDC9), then
read Table F using the FK/PK index (NDC9), then
read Table B using the FK.PK index (CPNUM) and then
sort it all in memory to remove the duplicates
(The order of R, F and B could differ, but should not matter for the
example I gave)
This way you will have a fully indexed search
The example you provided could not use an index to filter out the
records, so at least one table would need to be scan naturally, FB
chooses the smaller one.
> Record Counts:That explain why optimizer chooses to use it as the first for the scanning
> RNDC14: 1808
> CP_FDA_MAP: 24048
> CPNUM_BRANDNAME: 8871
> NDCLISTINGS: 60672
>
> RNDC14 is clearly the smallest table,
> but shouldn't the index be usedOnly if you provided a where clause that could use an index
> regardless?
>
will use an index:
where L.TradeName = 'Something'
where L.TradeName starts with 'Something'
where L.TradeName like 'Something%'
will not use an index
where L.TradeName <> 'Something'
where L.TradeName containing 'Something'
where L.TradeName like '%Something%'
your plan
PLAN
SORT (
JOIN (R NATURAL,
F INDEX (IDX_CP_FDA_MAP_NDC9),
B INDEX (IDX_CPNUM_CPNUM),
L INDEX (IDX_NDCLISTINGS_NDC9)
)
)
says:
Read table R from the first record to the end in the storage order, then:
read the record from table F using index IDX_CP_FDA_MAP_NDC9 to match
the clause (F.NDC9 = R.NDC9), then
read the record from table B using index IDX_CPNUM_CPNUM to match the
clause (B.CPNUM = F.CPNUM), then
read the record from table L using index IDX_NDCLISTINGS_NDC9 to match
the clause (L.NDC9 = R.NDC9), then
filter out the results where L.TRADENAME LIKE '%'||UPPER('aceta')||'%'
and then
sort out the result set in memory to remove all the duplicates
see you !
--
Alexandre Benson Smith
Development
THOR Software e Comercial Ltda
Santo Andre - Sao Paulo - Brazil
www.thorsoftware.com.br