Мой план запросов Firebird не использует правильный индекс - PullRequest
1 голос
/ 18 августа 2011

У меня проблема с индексами в моем запросе 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, 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 голосов
/ 02 сентября 2011

Это просто внутреннее чувство, но попробуйте также выбрать b.objid

0 голосов
/ 18 августа 2011

Прежде всего обновите статистику индексов, потому что 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:

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
...