1

我的 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) 降序

提前致谢

问候, 雷纳尔迪

4

2 回答 2

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
于 2011-08-18T12:24:07.653 回答
0

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

于 2011-09-02T08:48:23.183 回答