My firebird query plan does not use correct index
I have a problem with indexes in my firebird query.
Below is my query.
SELECT a.objid,
b.running_qty,
b.running_qty2,
b.running_totalcost,
b.running_lastcost
FROM mm_itrghd a,
mm_itrgdt b
WHERE (a.objid = b.header_id)
AND (b.item_id = 1200)
AND (b.wh_id = 1)
AND ((a.postdate < '2010-09-05 00:00:00') OR ((a.postdate = '2010-09-05 00:00:00') AND (a.objid < 50000)))
ORDER BY a.postdate desc,
a.objid desc,
b.calctyp desc,
b.objid desc
As you see, in order by section, we use desc. I have an开发者_JAVA百科 descending index, but my query plan does not use it. It only use index Table A (a.objid) and Table B (b.item_id, b.wh_id) Is there something i missed? What index do you think should i create?
Index for Table A (mm_itrghd)
(TR_CODE, DOC_ID) Ascending (OBJID) Ascending (TR_CODE) Ascending (POSTDATE) Ascending (POSTDATE, OBJID) Ascending (POSTDATE, OBJID) Descending
Index for Table B (mm_itrgdt)
(HEADER_ID) Ascending (ITEM_ID) Ascending (WH_ID) Ascending (LOT_NO) Ascending (SERIAL_NO, ITEM_ID) Ascending (HEADER_ID, ITEM_ID, WH_ID, SERIAL_NO, LOT_NO) Ascending (HEADER_ID, ITEM_ID, WH_ID) Ascending (CALCTYP, OBJID) Ascending (ITEM_ID, WH_ID) Ascending (CALCTYP, OBJID, ITEM_ID, WH_ID) Ascending (CALCTYP, OBJID) Descending (OBJID, ITEM_ID, WH_ID) Descending (OBJID) Descending
Thanks in advance
Regards, Reynaldi
First of all update indices statistics because Firebird relay on it when choosing what index to use and what not. Either do backup-restore cycle for database or execute following code:
EXECUTE BLOCK
AS
DECLARE VARIABLE IDX VARCHAR(31);
BEGIN
FOR
SELECT rdb$index_name FROM rdb$indices
WHERE NOT rdb$index_name LIKE 'RDB$%'
INTO :idx
DO BEGIN
EXECUTE STATEMENT 'update statistics ' || :idx
WITH AUTONOMOUS TRANSACTION;
END
END
Check the query plan after that. If index is not used it is because Firebird thinks that its usage will do more harm then help. You can either specify plan for query manually or try to rewrite it.
In your case you can get rid of OR condition using UNION operator:
select
a.postdate,
a.objid,
b.calctyp,
b.objid,
b.running_qty,
b.running_qty2,
b.running_totalcost,
b.running_lastcost
from
mm_itrghd a join mm_itrgdt b
on a.objid=b.header_id
where
(b.item_id=1200)
and (b.wh_id=1)
and (a.postdate<'2010-09-05 00:00:00')
union all
select
a.postdate,
a.objid,
b.calctyp,
b.objid,
b.running_qty,
b.running_qty2,
b.running_totalcost,
b.running_lastcost
from
mm_itrghd a join mm_itrgdt b
on a.objid=b.header_id
where
(b.item_id=1200)
and (b.wh_id=1)
and (a.postdate='2010-09-05 00:00:00')
and (a.objid<50000)
order by
1 desc, 2 desc, 3 desc, 4 desc
It's just a gut feeling, but try to also select b.objid
精彩评论