powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Агрегат в подзапросе сильно тормозит FETCH
17 сообщений из 17, страница 1 из 1
Агрегат в подзапросе сильно тормозит FETCH
    #40022985
гуманоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго!

БД FB SS 2.1.7. (поменять не могу - это сервер пользователя)
Сервер и клиент Win10 Prof

Есть запрос выбираются некоторые карточки изделий из таблицы изделий.
Есть таблица операций для каждого изделия.
В таблице операций признаком, что операция еще не выполнялась является отсутствие даты закрытия операции.

Мне нужно выбрать карточки изделий по некоторым параметрам, и у тех которые имеют не завершенные операции указать количество этих не завершенных операций.
Пробовал по всякому, подзапрос в запросе, джойнить подзапрос к основному запросу (поскольку не все изделия имеют не завершенные операции то тут соединял по ЛЕФТ),
создавал вьювер и джойнил к вьюверу, создавал временную таблицу и пытался залить туда агрегированные значения (вообще не вариант, более 20 минут идет запись в таблицу)...
Пытался делать запрос в виде Execute block
Бегу по выбранным изделиям и во внутреннем запросе отбираю подзапрос для данного изделия (ну это скорее уже от безисходности ))))


Если из запроса убрать все справочники, то он примет вид
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select T1.*,
       (select count(*) as OP
        from TABLE2 T2
        where T2.DATE_CLOSE is null and
              T2.CODECARDNUMBER = T1.CODECARDNUMBER) as OP
from TABLE1 T1
where T1.OTK = 1
order by T1.CARDNUM 



Вот реальный запрс
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select CARDNUMBER.OTK, ZAKAZ.CLIENTCODE, ZAKAZ.NUMBERZAKAZ, ZAKAZ.DATEIN, CARDNUMBER.CARDNUM, CARDNUMBER.DATEOTK,
       RECEIPTS.CODECARDNUMBER, RECEIPTS.CARD, CARDNUMBER.CODEMODEL, CARDNUMBER.CODECOLORR, CARDNUMBER.CODERAZMER,
       (select count(*) as OP
        from OPERATIONCARD OPERATIONCARD
        where OPERATIONCARD.DATE_CLOSE is null and
              OPERATIONCARD.CODECARDNUMBER = CARDNUMBER.CODECARDNUMBER) as OP
from CARDNUMBER CARDNUMBER
inner join RECEIPTS RECEIPTS on (CARDNUMBER.CODECARDNUMBER = RECEIPTS.CODECARDNUMBER)
inner join ZAKAZ ZAKAZ on (CARDNUMBER.CODEZAKAZ = ZAKAZ.CODEZAKAZ)
inner join MODEL MODEL on (CARDNUMBER.CODEMODEL = MODEL.CODEMODEL)
inner join RAZMER RAZMER on (RAZMER.CODERAZMER = CARDNUMBER.CODERAZMER)
inner join COLORR COLORR on (COLORR.CODECOLORR = CARDNUMBER.CODECOLORR)
inner join CLIENT CLIENT on (CLIENT.CLIENTCODE = ZAKAZ.CLIENTCODE)

where RECEIPTS.ADDSALES = 'F' and
      CARDNUMBER.OTK = 1 and
      CARDNUMBER.CODEBOX_CLIENT = 0 and
      RECEIPTS.CARD = 'готовая'
order by CARDNUMBER.CARDNUM  



На картинке план запроса из IBE. (приношу извинения не разобрался как вставить картинку в нужное место)
[img=]
Вариант с джойном

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
select CARDNUMBER.OTK, ZAKAZ.CLIENTCODE, ZAKAZ.NUMBERZAKAZ, ZAKAZ.DATEIN, CARDNUMBER.CARDNUM, CARDNUMBER.DATEOTK,
       RECEIPTS.CODECARDNUMBER, RECEIPTS.CARD, CARDNUMBER.CODEMODEL, CARDNUMBER.CODECOLORR, CARDNUMBER.CODERAZMER,
       DD.OP
from CARDNUMBER CARDNUMBER
inner join RECEIPTS RECEIPTS on (CARDNUMBER.CODECARDNUMBER = RECEIPTS.CODECARDNUMBER)
inner join ZAKAZ ZAKAZ on (CARDNUMBER.CODEZAKAZ = ZAKAZ.CODEZAKAZ)
inner join MODEL MODEL on (CARDNUMBER.CODEMODEL = MODEL.CODEMODEL)
inner join RAZMER RAZMER on (RAZMER.CODERAZMER = CARDNUMBER.CODERAZMER)
inner join COLORR COLORR on (COLORR.CODECOLORR = CARDNUMBER.CODECOLORR)
inner join CLIENT CLIENT on (CLIENT.CLIENTCODE = ZAKAZ.CLIENTCODE)
left join(select OPERATIONCARD.CODECARDNUMBER, count(*) as OP
          from OPERATIONCARD OPERATIONCARD
          where OPERATIONCARD.DATE_CLOSE is null
          group by OPERATIONCARD.CODECARDNUMBER) as DD on DD.CODECARDNUMBER = CARDNUMBER.CODECARDNUMBER
where RECEIPTS.ADDSALES = 'F' and
      CARDNUMBER.OTK = 1 and
      CARDNUMBER.CODEBOX_CLIENT = 0 and
      RECEIPTS.CARD = 'готовая'
order by CARDNUMBER.CARDNUM 



Результат тот же

В общем проблема следующая в таблице операций более 4 миллионов записей.
Запрос выполняется приемлимо около 2сек (запрс не оч. частый поэтому выполняется практически на "холодную". На горячую порядка 25мс),
однако ФЕТЧ все сводит на нет.

При выборке (среднее колмчество отбираемое основным запросом) около 4000 записей фетч идет где то около 30 сек.
Может есть какой то другой способ подсоединить агрегированные данные из одной таблицы к другой?

Спасибо.

З.Ы. Сильно не пинайте, искал по форуму, ничего не нашел. Если где то кто то помнит что есть такая тема или похожая ткните носом.
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40022996
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гуманоид,

посторонний вопрос - а на таблицах что, первичных и вторичных ключей вообще нет???
кроме того, зачем "картинка с планом", если план запроса вы можете вынуть текстом из IBE после prepare запроса?
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023002
гуманоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
CREATE UNIQUE INDEX NUM0 ON CARDNUMBER (CODECARDNUMBER);
CREATE INDEX CARDNUMBER_IDX1 ON CARDNUMBER (CARDNUM);
CREATE INDEX CARDNUMBER_IDX2 ON CARDNUMBER (CODERAZMER);
CREATE INDEX CARDNUMBER_IDX3 ON CARDNUMBER (CODECOLORR);
CREATE INDEX CARDNUMBER_IDX4 ON CARDNUMBER (CODEMODEL);
CREATE INDEX CARDNUMBER_IDX5 ON CARDNUMBER (CODEZAKAZ);
CREATE INDEX CARDNUMBER_ZAKAZDETAILED ON CARDNUMBER (CODEZAKAZDETAILED);

CREATE UNIQUE INDEX OPERATIONCARD_IDX1 ON OPERATIONCARD (CODEOPERATIONCARD);
CREATE INDEX OPERATIONCARD_IDX2 ON OPERATIONCARD (CODECARDNUMBER);
CREATE INDEX OPERATIONCARD_IDX3 ON OPERATIONCARD (NUMBERPERSON);
CREATE INDEX OPERATIONCARD_IDX4 ON OPERATIONCARD (CODEOPERATIONMODEL);
CREATE INDEX OPERATIONCARD_IDX5 ON OPERATIONCARD (ETAP);
CREATE INDEX OPERATIONCARD_IDX6 ON OPERATIONCARD (DATE_CLOSE);
CREATE INDEX OPERATIONCARD_IDX7 ON OPERATIONCARD (NUMBEROPERATION);
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023004
гуманоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kdv,
Ну вот по CTRL+F9 план запроса к первому варианту

Plan
PLAN (OPERATIONCARD INDEX (OPERATIONCARD_IDX2, OPERATIONCARD_IDX6))
PLAN SORT (JOIN (RECEIPTS INDEX (RECEIPTS_IDX4), CARDNUMBER INDEX (NUM0), RAZMER INDEX (RAZMER0), COLORR INDEX (COLORR0), ZAKAZ INDEX (ZAKAZ0), CLIENT INDEX (CLIENT0), MODEL INDEX (MODEL0)))
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023011
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гуманоид,

извиняюсь, а ЧТО ЭТО? база создавалась во времена царя Гороха, или разработчик не знал про ПК и ФК?
Это вообще все индексы? На других таблицах никаких индексов нет?
Это вопрос почти риторический, я не предлагаю тут вываливать метаданные.
Просто вот есть таблица RAZMER. И на ней что, индексов нет вообще?
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023014
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сколько времени занимает выполнение запроса без агрегата (с полным фетчем!) ?
Изменился ли план запроса в этом случае ?

Если тормозит таки агрегат, то для начала я бы (хинтом) отключил индекс по OPERATIONCARD.DATE_CLOSE.
Или создал бы композит по CODECARDNUMBER, DATE_CLOSE.



PS Алиасы к таблицам - это хорошо и правильно, но когда они совпадают с именами таблиц - глупо и не нужно.
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023015
гуманоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kdv,

Да база создавалась в InterBase, "до революции при немцах", когда еще ФБ даже не был в проекте.
Вот состав базы и диалект там еще старый. (На картинке.)
Вопрос не в том что это устарело, а в том можно ли его заставить работать шустрее.

hvlad,

Проверенно, тормозит именно агрегат.
Вот в таком виде
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
select CARDNUMBER.OTK, ZAKAZ.CLIENTCODE, ZAKAZ.NUMBERZAKAZ, ZAKAZ.DATEIN, CARDNUMBER.CARDNUM, CARDNUMBER.DATEOTK,
       RECEIPTS.CODECARDNUMBER, RECEIPTS.CARD, CARDNUMBER.CODEMODEL, CARDNUMBER.CODECOLORR, CARDNUMBER.CODERAZMER
from CARDNUMBER CARDNUMBER
inner join RECEIPTS RECEIPTS on (CARDNUMBER.CODECARDNUMBER = RECEIPTS.CODECARDNUMBER)
inner join ZAKAZ ZAKAZ on (CARDNUMBER.CODEZAKAZ = ZAKAZ.CODEZAKAZ)
inner join MODEL MODEL on (CARDNUMBER.CODEMODEL = MODEL.CODEMODEL)
inner join RAZMER RAZMER on (RAZMER.CODERAZMER = CARDNUMBER.CODERAZMER)
inner join COLORR COLORR on (COLORR.CODECOLORR = CARDNUMBER.CODECOLORR)
inner join CLIENT CLIENT on (CLIENT.CLIENTCODE = ZAKAZ.CLIENTCODE)
where RECEIPTS.ADDSALES = 'F' and
      CARDNUMBER.OTK = 1 and
      CARDNUMBER.CODEBOX_CLIENT = 0 and
      RECEIPTS.CARD = 'готовая'
order by CARDNUMBER.CARDNUM


Запрос выполняется 600мс фетчится полностью - мгновенно
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023016
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гуманоидДа база создавалась в InterBase, "до революции при немцах"
да что вы говорите. в Interbase 4 в 1995 году были стандартные primary/foreign key. И при чем тут FB?
Короче, по уму надо
- все индексы, имитирующие ПК и ФК убить
- создать нормальные ПК и ФК НА ВСЕХ таблицах
- после чего запрос повторить.
теоретически, агрегат этот ускорить никак не получится, надо его превратить в хранимый вместо вычисляемого. Тогда сильно полегчает.
А так - нахрена постоянно count/group by базу долбать, непонятно.
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023018
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гуманоид
Запрос выполняется 600мс фетчится полностью - мгновенно
Я задавал ещё и вопрос о его плане.
Отвечайте на все вопросы или не отвечайте вообще, уважайте чужое время.
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023019
гуманоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробую индексы переделать.
Извините за непонятливость
авторнадо его превратить в хранимый вместо вычисляемого.
Имеется в виду ввести поле в таблицу куда помещать результат count или можно создать ХП и ее джойнить к запросу, хотя это тоже вычислимое выходит?
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023020
гуманоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvlad,
Прошу прощения.
Вот план от этого запроса
Plan
PLAN SORT (JOIN (RECEIPTS INDEX (RECEIPTS_IDX4), CARDNUMBER INDEX (NUM0), RAZMER INDEX (RAZMER0), COLORR INDEX (COLORR0), ZAKAZ INDEX (ZAKAZ0), CLIENT INDEX (CLIENT0), MODEL INDEX (MODEL0)))
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023021
гуманоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hvlad,

авторЕсли тормозит таки агрегат, то для начала я бы (хинтом) отключил индекс по OPERATIONCARD.DATE_CLOSE.
Или создал бы композит по CODECARDNUMBER, DATE_CLOSE.
Попробую чуть позже. Сейчас вынужден отлучиться.
Спасибо за помощь.
А да, композит по DATE_CLOSE "рассыпет " выборку на множество записей изделий по разным датам закрытия операций. Это не вариант. Создавал такой во вьювере.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
CREATE VIEW COUNTOP(
    CODECARDNUMBER,
    DATECLOSE,
    OP)
AS
select OPERATIONCARD.CODECARDNUMBER,OPERATIONCARD.DATE_CLOSE,iif(OPERATIONCARD.DATE_CLOSE is null ,count(*),null) as OP
from OPERATIONCARD OPERATIONCARD
--where OPERATIONCARD.DATE_CLOSE is null
group by OPERATIONCARD.CODECARDNUMBER,OPERATIONCARD.DATE_CLOSE


В выборке нужна одна запись с количеством не закрытых операций.
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023040
hvlad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гуманоид
А да, композит по DATE_CLOSE "рассыпет " выборку на множество записей изделий по разным датам закрытия операций. Это не вариан
Композит в данном контексте, - это композитный индекс по нескольким полям.
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023047
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гуманоидИмеется в виду ввести поле в таблицу куда помещать результат count или можно создать ХП и ее джойнить к запросу, хотя это тоже вычислимое выходит?
Не процедуру, спаси господи, это будет то же самое, только "сбоку".
Насчет хранимого агрегата - смотрите, у вас сейчас там 4 миллиона записей, и "тормозит". Завтра, через месяц, через год у вас будет 10 миллионов записей (допустим), и тормозить будет еще больше.
Зачем постоянно считать одно и то же? сделайте таблицу, в которой будут вот эти самые агрегированные значения. Пересчитывать их можно процедурой, чем угодно, периодически, с нужным интервалом.
Например, в бухгалтериях так всегда делается - типа "закрытие месяца" - считаются данные за месяц, и сохраняются, чтобы их потом не считать каждый раз снова.
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023051
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdv
гуманоидИмеется в виду ввести поле в таблицу куда помещать результат count или можно создать ХП и ее джойнить к запросу, хотя это тоже вычислимое выходит?

Не процедуру, спаси господи, это будет то же самое, только "сбоку".
Насчет хранимого агрегата - смотрите, у вас сейчас там 4 миллиона записей, и "тормозит". Завтра, через месяц, через год у вас будет 10 миллионов записей (допустим), и тормозить будет еще больше.
Зачем постоянно считать одно и то же? сделайте таблицу, в которой будут вот эти самые агрегированные значения.

По скромному моему разумению тут и отдельная таблица не нужна. Поле в таблице CARDNUMBER, содержащее количество записей с null в OPERATIONCARD.DATE_CLOSE, ведущееся на триггерах OPERATIONCARD.
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023092
гуманоид
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kdvНапример, в бухгалтериях так всегда делается - типа "закрытие месяца" - считаются данные за месяц, и сохраняются, чтобы их потом не считать каждый раз снова.
Ну, тут задача немного не бухгалтерская. Информация динамическая и нужно знать ее в момент запроса пользователем. Посему раз в месяц не катит.
Старый плюшевый мишка


По скромному моему разумению тут и отдельная таблица не нужна. Поле в таблице CARDNUMBER, содержащее количество записей с null в OPERATIONCARD.DATE_CLOSE, ведущееся на триггерах OPERATIONCARD.

Да, да. Так и сделал. Поле туда завет и попытался сперва его отапдейтить. Как писал выше, если по полной апдейтить, то более 20 минут. Завтра поганяю. Тут тоже не все так просто. Одновременно получают дату закрытия до нескольких тысячей записей. Надо посмотреть как триггерок с этим совладает.
...
Рейтинг: 0 / 0
Агрегат в подзапросе сильно тормозит FETCH
    #40023096
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
гуманоидНу, тут задача немного не бухгалтерская. Информация динамическая и нужно знать ее в момент запроса пользователем
бухгалтерия тут просто как пример.
А насчет динамической информации и "нужно знать" - это сказки. Прямо вот пользователь хочет узнать, какие там количества по 4м миллионам единиц информации? Да он будет тупо смотреть в такой отчет полдня.

К примеру, тут вероятно не хранимые агрегаты нужны, а раделение на "закрытые операции" и незакрытые. У нас была система, в которой хранилось дофига данных, и вот заполнено полезной информацией было только 30%. А считать приходилось всё, целиком.
Ну и взяли, создали еще одну таблицу, в которую заносили только "заполненную" информацию. А остальная шлабуда была в большой таблице. Поскольку дополнительная таблица была короче, ее объем получился раз в 20 меньше исходной. И отчеты стали просто летать.
Это при том, что часть информации дублировалась в старой и новой таблице.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Агрегат в подзапросе сильно тормозит FETCH
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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