FB2 (НУ ВООЩЕ !!!)

ЧАстые Вопросы и Ответы

Модераторы: kdv, CyberMax

Ответить
Дамир
Сообщения: 4
Зарегистрирован: 15 ноя 2006, 13:37

FB2 (НУ ВООЩЕ !!!)

Сообщение Дамир » 22 дек 2006, 19:59

Два дня исследовал такой феномен FB 2:
имеем таблицу

Код: Выделить всё

CREATE TABLE DOK_TOVAR_FAKT
 (CODE               INTEGER       NOT NULL PRIMARY KEY,
  TOVARLINK          INTEGER       NOT NULL REFERENCES SPRAV, /* номенклатура */
  DATA               TIMESTAMP     ,
  PARTIALINK         INTEGER       ,    
  SUMMA              NUMERIC(15,2) DEFAULT 0 NOT NULL, 
  CENA               NUMERIC(15,2) DEFAULT 0 NOT NULL, 
  KOL                NUMERIC(15,4) DEFAULT 0 NOT NULL,  -- там  >0 (приход) <0 (расход) 
  .....);  
CREATE INDEX FAKT_PARTIA_IDX ON DOK_TOVAR_FAKT(PARTIALINK);
CREATE INDEX FAKT_PARTIA_DATA_IDX ON DOK_TOVAR_FAKT(DATA);
ЭТО типа регистра 1С
Задача узнать остаток ПО "TOVARLNK" на дату. Думаю просто и радуюсь своей крутизне :)

Код: Выделить всё

CREATE PROCEDURE TOVAR_OSTATOK
 (TOVAR          INTEGER,
  DATA           DATE)
RETURNS
 (OSTATOK        NUMERIC(15,4))
AS
 DECLARE VARIABLE KOL NUMERIC(15,4);
 DECLARE VARIABLE WDATA DATE;
BEGIN
 select sum(KOL) from DOK_TOVAR_FAKT  where (TOVARLINK = :TOVAR) and (DATA<=:DATA)
 into :OSTATOK;
 suspend;
END
Запустил это для выборки 15 тыс.товаров. Уснул (несколько минут - точно)
не поверил глазам - стал исследовать IBExpertom - скорость 40-60 ms на один товар
причем если убрать "and (DATA<=:DATA) " быстрее в РАЗЫ !!! хотя чтения индексированные
и прочитано в среднем по 3-и записи на товар

поэтому написал следующее :

Код: Выделить всё

CREATE PROCEDURE TOVAR_OSTATOK
 (TOVAR          INTEGER,
  DATA           DATE)
RETURNS
 (OSTATOK        NUMERIC(15,4))
AS
 DECLARE VARIABLE KOL NUMERIC(15,4);
 DECLARE VARIABLE WDATA DATE;
BEGIN
 OSTATOK = 0;
 for select DATA,kol from DOK_TOVAR_FAKT
   where (TOVARLINK = :TOVAR)
   into :WDATA,:KOL
 do begin
  if (WDATA <= :DATA) then
   OSTATOK = OSTATOK + KOL;
 end
 suspend;
END^

Эта штуковина выводит 15 тыс товаров за 4 секунды


ВОПРОС - ПОЧЕМУ и КАК С ЭТИМ ЖИТЬ !?
===================================
Просьба не зацикливаться на примере, а по существу ...

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 23 дек 2006, 00:32

Запустил это для выборки 15 тыс.товаров. Уснул (несколько минут - точно)
ты оригинал. 15 тысяч раз вызвать процедуру, в которой select sum - это, типа, нормально, и должно выполняться моментально?
Что написал, то и получил, собственно.
причем если убрать "and (DATA<=:DATA) " быстрее в РАЗЫ !!!
при поиске по индексу строится массив с номерами записей, затем сортируется. Два индекса - по очереди, потом над результатом делается and или or, что написано в запросе. Если у индекса плохая селективность, т.е. мало разных значений, то массив будет большой и его обработка будет дольше.
Значит, по товару селективность индекса выше, чем по дате. Опять же, умножаем это на 15 тысяч раз.
ВОПРОС - ПОЧЕМУ и КАК С ЭТИМ ЖИТЬ !?
думать надо. сервер не волшебным образом выбирает данные, а посредством различных конкретных механизмов доступа. Собственно, загнуть производительность можно на любом сервере, легко.

p.s. я не понял, чем тебя group by не устроил?

Ответить