powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите ускорить выполнение запроса Firebird
20 сообщений из 20, страница 1 из 1
Помогите ускорить выполнение запроса Firebird
    #39078501
tarakan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, использую БД firebird 2.5, Delphi xe2, fibplus + ehlib
Таблица SALE
Код: sql
1.
2.
3.
4.
5.
6.
7.
ID(integer) - счетчик ,
TID(integer) - ID товара,
KE(DECIMAL 12,5) - количество,
DOCTYPEID(integer) - ID типа документа,
DOCID(integer) - ID документа,
DDOC(TIMESTAMP) - Дата документа
… 

Сейчас в этой таблице около 500 тыс записей и возникла надобность узнавать количество конкретного товара на дату документа.
Я составил запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT 
  S1.ID,
  S1.KE,
  S1.DDOC,
  (SELECT SUM(S2.KE) AS FIELD_1 FROM SALE S2 WHERE S2.TID = 1005 AND S2.DDOC <= S1.DDOC) AS OSTATOKNADATU
FROM
  SALE S1
WHERE
  S1.TID = 1005
ORDER BY
  S1.DDOC DESC



Запрос выполняется ОЧЕНЬ долго, не могли бы Вы дать рекомендации по ускорению этого запроса.
P.S. Индексы в таблице SALE по полям : TID,DOCTYPEID, DOCID, DDOC, составной индекс TID,DDOC
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078514
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078889
tarakan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Насколько я понял, там обсуждается общее текущее количество товара и при том, как я понял, могу и ошибаться, при многопользовательском режиме это не катит, а меня интересует количество товара на конкретную дату документа.
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078895
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tarakanдать рекомендации по ускорению этого запроса.применять хранимые агрегаты.
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078898
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tarakanмогу и ошибаться, при многопользовательском режиме это не катит, а меня интересует количество товара на конкретную дату документа.Как раз при многопольз. режиме только та схема и катит . Вам следует только добавить в сальдовую таблицу поле с датой (ну, или строковое в виде даты + значения часов от полуночи) и агрегировать по коду товара и значению "якорного" момента времени.
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078899
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tarakan,

Про хранимые агрегаты уже сказали. В тройке можно ещё воспользоваться вот этим запросом, который будет намного эффективнее

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT 
  S.ID,
  S.KE,
  S.DDOC,
  SUM(S.KE) OVER(ORDER BY S.DDOC) AS OSTATOKNADATU
FROM
  SALE S
WHERE
  S.TID = 1005
ORDER BY
  S.DDOC DESC
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078907
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисВ тройке можно ещё воспользоваться вот этим запросом, который будет намного эффективнееТерзают смутные сомнения как бэ...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
recreate table sale(id int primary key, ke int, ddoc int, tid int);
commit;
create index sale_tid on sale(tid);
create descending index sale_ddoc_desc on sale(ddoc);
commit;

SQL> set planonly;
SQL> select
CON>     s.id,
CON>     s.ke,
CON>     s.ddoc,
CON>     sum(s.ke) over(order by s.ddoc desc) as ostatoknadatu
CON> from sale s
CON> where s.tid = 1005
CON> order by s.ddoc desc;

PLAN  SORT  ( SORT  (S INDEX (SALE_TID)))
SQL> set explain on;
SQL> select
CON>     s.id,
CON>     s.ke,
CON>     s.ddoc,
CON>     sum(s.ke) over(order by s.ddoc desc) as ostatoknadatu
CON> from sale s
CON> where s.tid = 1005
CON> order by s.ddoc desc;

Select Expression
    -> Sort (record length: 60, key length: 8)
        -> Window
            -> Record Buffer (record length: 65)
                -> Sort (record length: 68, key length: 8)
                    -> Window
                        -> Record Buffer (record length: 33)
                            -> Filter
                                -> Table "SALE" as "S" Access By ID
                                    -> Bitmap
                                        -> Index "SALE_TID" Range Scan (full match)

ЗЫ. Никогда не понимал, что мешало реализовать оконные ф-ции так, чтобы они юзали индекс при его наличии...
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078910
tarakan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ТаблоидВам следует только добавить в сальдовую таблицу поле с датой (ну, или строковое в виде даты + значения часов от полуночи) и агрегировать по коду товара и значению "якорного" момента времени.
А можно подробнее, для тех, кто на бронепоезде?
Симонов Денис В тройке можно ещё воспользоваться вот этим запросом, который будет намного эффективнее
У меня менеджер не знает слова OVER и ругается на открытую скобку в выражении OVER(ORDER BY S.DDOC)
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078916
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tarakan,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
CREATE TABLE MOVEMENTS (
 GOOD INTEGER NOT NULL REFERENCES GOODS,
  MOVEMENT_DTS TIMESTAMP ,
 AMOUNT INTEGER NOT NULL);

CREATE TABLE GOODS_AMOUNTS_AGG (
  GOOD INTEGER NOT NULL REFERENCES GOODS,
   SNAPSHOT_HOUR INT ,
  AMOUNT INTEGER NOT NULL);

CREATE PROCEDURE GOODS_AMOUNT_ROLL_UP AS
DECLARE GOOD INTEGER;
DECLARE TOTAL INTEGER;
 DECLARE SNAPSHOT_HOUR INT; 
BEGIN
    FOR 
        SELECT GOOD,  DATEDIFF(HOUR FROM TIMESTAMP '01.01.2015' TO MOVEMENT_DTS) ,  SUM(AMOUNT) 
        FROM  GOODS_AMOUNT_AGG 
        GROUP BY GOOD,  DATEDIFF(HOUR FROM TIMESTAMP '01.01.2015' TO MOVEMENT_DTS) 
        HAVING COUNT(*)>1
    INTO :GOOD,  :SNAPSHOT_HOUR , :TOTAL 
    DO
    BEGIN
       DELETE FROM GOODS_AMOUNT_AGG 
       WHERE GOOD=:GOOD AND  DATEDIFF(HOUR FROM TIMESTAMP '01.01.2015' TO MOVEMENT_DTS) = :SNAPSHOT_HOUR ;
       INSERT INTO GOODS_AMOUNT_AGG (GOOD,  SNAPSHOT_HOUR , AMOUNT) 
       VALUES(:GOOD,  :SNAPSHOT_HOUR , :TOTAL);
    END
END
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078922
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

1. конкретно в этом запросе использование индекса только бы навредило, поскольку всё равно надо выбрать все записи с TID = 1005

2. я намеренно применил asc сортировку в OVER. Твой запрос даст совсем не то

Запрос с использованием оконной функции будет эффективнее в N раз, поскольку выборка из SALE делается только один раз. Естественно при условии что достаточно памяти в TempCacheLimit
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078930
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисЗапрос с использованием оконной функции будет эффективнее в N разУ тебя есть конкретные результаты измерений *с* оконной ф-цией =vs= хранимые агрегаты ?
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078933
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Таблоид,

хранимые агрегаты конечно же уделают любой запрос с агрегатами и оконными функциями. Речь шла про запрос автора vs запрос с использованием оконных функций
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39078987
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tarakanпри многопользовательском режиме это не катит
при многопользовательском режиме не катит заниматься онанизмом (извините за прямоту), то есть постоянно пересчитывать одни и те же данные, причем объем которых увеличивается регулярно.
Хранимые агрегаты придуманы именно для этого.

tarakanУ меня менеджер не знает слова OVER
кто такой "менеджер", и какое ему дело до синтаксиса ФБ 3? Он не может просто отправить запрос на сервер?
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39079030
tarakan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kdvзаниматься онанизмом (извините за прямоту),...
Хранимые агрегаты придуманы именно для этого.
Спасибо за прямоту, понял, был не прав сейчас читаю, разбираюсь, пока еще недостаточно образован для использования хранимых агрегатов, короче учу мат часть.

Отдельное спасибо Таблоид

kdvкто такой "менеджер", и какое ему дело до синтаксиса ФБ 3? Он не может просто отправить запрос на сервер?
SQL Manager for InterBase & Firebird, я писал в первом посте(у), что использую ФБ 2,5; так что до over'a мне еще 0,5 ФБ :)
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39079049
Alex Truhin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL Manager for InterBase & Firebird, я писал в первом посте(у), что использую ФБ 2,5; так что до over'a мне еще 0,5 ФБ :)
Выбрось каку и скачай нормальный IBExpert
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39079288
tarakan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Таблоидtarakan,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
CREATE TABLE MOVEMENTS (
 GOOD INTEGER NOT NULL REFERENCES GOODS,
  MOVEMENT_DTS TIMESTAMP ,
 AMOUNT INTEGER NOT NULL);

CREATE TABLE GOODS_AMOUNTS_AGG (
  GOOD INTEGER NOT NULL REFERENCES GOODS,
   SNAPSHOT_HOUR INT ,
  AMOUNT INTEGER NOT NULL);

CREATE PROCEDURE GOODS_AMOUNT_ROLL_UP AS
DECLARE GOOD INTEGER;
DECLARE TOTAL INTEGER;
 DECLARE SNAPSHOT_HOUR INT; 
BEGIN
    FOR 
        SELECT GOOD,  DATEDIFF(HOUR FROM TIMESTAMP '01.01.2015' TO MOVEMENT_DTS) ,  SUM(AMOUNT) 
        FROM  GOODS_AMOUNT_AGG 
        GROUP BY GOOD,  DATEDIFF(HOUR FROM TIMESTAMP '01.01.2015' TO MOVEMENT_DTS) 
        HAVING COUNT(*)>1
    INTO :GOOD,  :SNAPSHOT_HOUR , :TOTAL 
    DO
    BEGIN
       DELETE FROM GOODS_AMOUNT_AGG 
       WHERE GOOD=:GOOD AND  DATEDIFF(HOUR FROM TIMESTAMP '01.01.2015' TO MOVEMENT_DTS) = :SNAPSHOT_HOUR ;
       INSERT INTO GOODS_AMOUNT_AGG (GOOD,  SNAPSHOT_HOUR , AMOUNT) 
       VALUES(:GOOD,  :SNAPSHOT_HOUR , :TOTAL);
    END
END

Скажите Таблоид , можно ли как то связаться с Вами лично, можете мне написать на почту admin@strbit.ru или в skype : tarakan1983 ?
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39079549
Таблоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tarakan,

р 5 1 9 4 4 6 собацька у а n d е х . р у

(только зачем вы процитировали портянку перед своим вопросом ? :))
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39079561
tarakan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Таблоидtarakan,
(только зачем вы процитировали портянку перед своим вопросом ? :))
Нечаянно.
Отписался на почту.
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39084357
DBConstructor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
tarakan, DDL всех индексов таблицы в студию.
...
Рейтинг: 0 / 0
Помогите ускорить выполнение запроса Firebird
    #39084698
tarakan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DBConstructortarakan, DDL всех индексов таблицы в студию.
Да вроде уже разобрались со всем, спасибо большое всем за участие, особый плюсик Таблоид
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите ускорить выполнение запроса Firebird
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]