我的firebird查询计划不使用正确的索引

时间:2011-08-18 04:35:57

标签: sql database firebird interbase

我的firebird查询中的索引存在问题。

以下是我的查询。

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

如您所见,按部分顺序,我们使用desc。我有一个降序索引,但我的查询计划不使用它。 它只使用索引表A(a.objid)和表B(b.item_id,b.wh_id) 我错过了什么吗?你认为我应该创建什么指数?

表A的索引(mm_itrghd)

(TR_CODE,DOC_ID)升序 (OBJID)升序 (TR_CODE)升序 (POSTDATE)升序 (POSTDATE,OBJID)升序 (POSTDATE,OBJID)降序

表B的索引(mm_itrgdt)

(HEADER_ID)升序 (ITEM_ID)升序 (WH_ID)升序 (LOT_NO)升序 (SERIAL_NO,ITEM_ID)升序 (HEADER_ID,ITEM_ID,WH_ID,SERIAL_NO,LOT_NO)升序 (HEADER_ID,ITEM_ID,WH_ID)升序 (CALCTYP,OBJID)升序 (ITEM_ID,WH_ID)升序 (CALCTYP,OBJID,ITEM_ID,WH_ID)升序 (CALCTYP,OBJID)降序 (OBJID,ITEM_ID,WH_ID)降序 (OBJID)降序

提前致谢

此致 Reynaldi

2 个答案:

答案 0 :(得分:0)

首先更新索引统计信息,因为在选择要使用的索引和不使用的索引时,Firebird会对其进行中继。对数据库执行备份 - 还原循环或执行以下代码:

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

之后检查查询计划。如果没有使用索引,那是因为Firebird认为它的使用会带来更大的伤害然后帮助。您可以手动指定查询计划或尝试重写它。

在您的情况下,您可以使用UNION运算符删除OR条件:

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

答案 1 :(得分:0)

这只是一种直觉,但也尝试选择b.objid