开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜