Subject | Re: Query Optimization |
---|---|
Author | Svein Erling Tysvær |
Post date | 2004-10-20T07:35:40Z |
Hi again Juan!
and do left joins is not. Anyway, does this mean that you could get
the result you want using inner joins? If so, I'd be much more
comfortable with your query.
the end whether it is identical to the SP, slower or faster (I don't
think you can make a straigth join much faster than an optimized
stored procedure, but I'm not yet convinced your SP is optimized).
opinion) is that it tries to use too many indexes. Combine that with
someone who creates too many indexes and Firebird gets unbearably
slow. Having an index on STATUS is normally not a good choice, unless
the selects based on STATUS normally obtain those records which has an
unusual status (i.e. a search on STATUS = '1. prize' in a lottery
could benefit from an index).
Change your query to
SELECT B.TB_INSPECT_ID
FROM TB_INSPECT_GROUP A inner JOIN TB_INSPECT B
ON (B.INSPECTION_GROUP_ID = A.TB_INSPECT_GROUP_ID)
WHERE A.DEST_LOT_ID IS NULL
AND A.SO_DET_ID IS NOT NULL
AND (B.WRITE_UP_DET_ID IS NULL
AND B.STATUS IN ('PASSED','USE AS IS') OR 2=0)
This should prevent IDX_TB_INSPECT_WUP_DET and IDX_TB_INSPECT_STATUS
from being used with this query.
the (... OR 2=0) above.
are better than inner joins combined with the creation of too many
indexes.
Set
> The first thing that I discontinue in interbase was the INNER JOINForget MSAccess and do IB is a good idea, but to forget inner joins
> and adopted LEFT JOIN because A LOT of times inner joins
> took "forever" and LEFT JOIN gave me the result pretty fast (just
> take care of nulls when necessary). I just thought "ok, IB just work
> this way. Let's forget MSACCESS and do IB".
and do left joins is not. Anyway, does this mean that you could get
the result you want using inner joins? If so, I'd be much more
comfortable with your query.
> The same example from the begining (LEFT JOIN 1.4 sec)It should at least be possible to optimize, then we will find out in
> ******************************************************
> SELECT B.TB_INSPECT_ID
> FROM TB_INSPECT_GROUP A LEFT JOIN TB_INSPECT B
> ON (B.INSPECTION_GROUP_ID = A.TB_INSPECT_GROUP_ID)
> WHERE
> A.DEST_LOT_ID IS NULL
> AND A.SO_DET_ID IS NOT NULL
> AND B.WRITE_UP_DET_ID IS NULL
> AND B.STATUS IN ('PASSED','USE AS IS')
>
> PLAN JOIN (A INDEX (RDB$FOREIGN132),B INDEX (RDB$FOREIGN112)):
> takes 1.43sec
>
> Do you think there's a way to write the original query in FB (only
> one select statement) and be optimized as in the SP?
the end whether it is identical to the SP, slower or faster (I don't
think you can make a straigth join much faster than an optimized
stored procedure, but I'm not yet convinced your SP is optimized).
> Modified example using (INNER JOIN cancel after 1+ minutes)And this reveals the problem. One of the weaknesses of Firebird (in my
> ******************************************************
>
> SELECT B.TB_INSPECT_ID
> FROM TB_INSPECT_GROUP A inner JOIN TB_INSPECT B
> ON (B.INSPECTION_GROUP_ID = A.TB_INSPECT_GROUP_ID)
> WHERE
> A.DEST_LOT_ID IS NULL
> AND A.SO_DET_ID IS NOT NULL
> AND B.WRITE_UP_DET_ID IS NULL
> AND B.STATUS IN ('PASSED','USE AS IS')
>
> PLAN JOIN (A INDEX (RDB$FOREIGN132),B INDEX
> (IDX_TB_INSPECT_WUP_DET,RDB$FOREIGN112,IDX_TB_INSPECT_STATUS,
> IDX_TB_INSPECT_STATUS)):
opinion) is that it tries to use too many indexes. Combine that with
someone who creates too many indexes and Firebird gets unbearably
slow. Having an index on STATUS is normally not a good choice, unless
the selects based on STATUS normally obtain those records which has an
unusual status (i.e. a search on STATUS = '1. prize' in a lottery
could benefit from an index).
Change your query to
SELECT B.TB_INSPECT_ID
FROM TB_INSPECT_GROUP A inner JOIN TB_INSPECT B
ON (B.INSPECTION_GROUP_ID = A.TB_INSPECT_GROUP_ID)
WHERE A.DEST_LOT_ID IS NULL
AND A.SO_DET_ID IS NOT NULL
AND (B.WRITE_UP_DET_ID IS NULL
AND B.STATUS IN ('PASSED','USE AS IS') OR 2=0)
This should prevent IDX_TB_INSPECT_WUP_DET and IDX_TB_INSPECT_STATUS
from being used with this query.
> See the original example. It should enter only 237 times to the lastReport back the results after changing your SQL to use inner joins and
> tables, but it goes thousands.
the (... OR 2=0) above.
> I'm not really sure if those optimizations "already happens" atI think your issue largely is due to the assumption that left joins
> least (I think) not in my databases. May be you already do it, but a
> big "real" databases already working could help to test the engine.
>
> Don't misunderstand me, I wanted to report this issue (optimization)
> because I haven't seen much real complains about this.
are better than inner joins combined with the creation of too many
indexes.
Set