Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
mmm_kazan Участник со стажем
Вступление в Клуб: 28.03.2018
|
Вт Апр 10, 2018 08:27  Обработка таблицы MAIN_DOCUM |
|
Полезность: Нет оценки
|
Всем доброго дня.
Вопрос такой:
Есть отчет со многими колонками
Всем нравится
Но стал очень громоздким - по многим причинам
Много приходится делать циклов типа
for(select md1 (sum(md1.[SUM]) : m_sum,
(case when md1.[KL_KT].[0] = 1
then substr(md1.[KL_KT].[1].[2].[MAIN_V_ID],1,5)
else substr(md1.[KL_KT].[2].[1],1,5)
end) : debet_oborot_str)
in ::[MAIN_DOCUM] all
where md1.[ACC_DT] = c.[af_id]
and (md1.[DATE_PROV] >= DATE_BEGIN)
and (md1.[DATE_PROV] <= DATE_END)
and md1%state='PROV'
group by (case when md1.[KL_KT].[0] = 1
then substr(md1.[KL_KT].[1].[2].[MAIN_V_ID],1,5)
else substr(md1.[KL_KT].[2].[1],1,5)
end)
order by 1 desc)
loop
if debet_oborot >0 then
debet_oborot_str := debet_oborot_str||md1.debet_oborot_str||to_char(md1.m_sum,'999999999999999.99')||'('||to_char(md1.m_sum/debet_oborot*100,'999.99')||'%)'||chr(10);
end if;
end loop;
debet_oborot_str:=debet_oborot_str||'Итого: '||to_char(debet_oborot,'999999999999999.99');
Придумать можно что-то?
Результат отчета прилагаю.
Скорее вопрос больше административный. |
|
 |
Volod Эксперт
Вступление в Клуб: 19.09.2007
|
Вт Апр 10, 2018 09:36   |
|
Полезность: Нет оценки
|
Все колонки вычислять в одном селекте.
Что значит громоздкий - 2 часа считает? |
|
 |
mmm_kazan Участник со стажем
Вступление в Клуб: 28.03.2018
|
Вт Апр 10, 2018 09:55   |
|
Полезность: Нет оценки
|
Селекты там разные
Вот второй
for(select md (sum(md.[SUM]) :m_sum)
in ::[MAIN_DOCUM] all
where md.[ACC_DT] = c.[af_id]
and md.[DATE_PROV] >= DATE_BEGIN
and md.[DATE_PROV] <= DATE_END
and md%state = 'PROV'
and (substr(md.[KL_KT].[1].[2].[MAIN_V_ID],1,5) = '40101' or
substr(md.[KL_KT].[2].[1],1,5) = '40101'))
loop
begin
nalog_oborot := md.m_sum;
exception when NO_DATA_FOUND or TOO_MANY_ROWS then
nalog_oborot := nalog_oborot;
end;
exit;
end loop;
Не 2 часа, но долго, если по многим организациям запустить.
С полчаса по приличной выборке. |
|
 |
mmm_kazan Участник со стажем
Вступление в Клуб: 28.03.2018
|
Вт Апр 10, 2018 09:56   |
|
Полезность: Нет оценки
|
А таких селектов порядка 10
Запускаются по каждой организации. |
|
 |
mmm_kazan Участник со стажем
Вступление в Клуб: 28.03.2018
|
Вт Апр 10, 2018 09:58   |
|
Полезность: Нет оценки
|
Хотя может и правда - сделать один селект, а внутри if делать. |
|
 |
pas Профи
Вступление в Клуб: 20.11.2007
|
Вт Апр 10, 2018 11:01   |
|
Полезность: Нет оценки
|
401 счетов много?
Лучше селект делать через выписку, быстрее будет. |
|
 |
mmm_kazan Участник со стажем
Вступление в Клуб: 28.03.2018
|
Вт Апр 10, 2018 11:09   |
|
Полезность: Нет оценки
|
pas пишет: | 401 счетов много?
Лучше селект делать через выписку, быстрее будет. |
Не много, но есть. Другие селекты посложнее. Там и по назначениям платежей есть.
А пример через выписку сможешь предложить? |
|
 |
Alkov Профи
Вступление в Клуб: 23.09.2010
|
Вт Апр 10, 2018 11:48   |
|
Полезность: Нет оценки
|
Вообще план надо смотреть, в идеале трейс , какой индекс цепляется,
большой ли период обычно по P_DATE_DEIGIN - P_DATE_END...
вот тут например substr(md.[KL_KT].[1].[2].[MAIN_V_ID],1,5) = '40101'
substr отключает индекс специально ?
, можно же было сделать md.[KL_KT].[1].[2].[MAIN_V_ID] like '40101%' |
|
 |
mmm_kazan Участник со стажем
Вступление в Клуб: 28.03.2018
|
Вт Апр 10, 2018 13:10   |
|
Полезность: Нет оценки
|
Я понимаю, что индескс наверное не тот.
Очень много конструкций OR.
Выслал все, что есть. |
|
 |
Volod Эксперт
Вступление в Клуб: 19.09.2007
|
Вт Апр 10, 2018 14:45   |
|
Полезность: Нет оценки
|
Дело не в индексе.
Это простая операция или групповая?
Практически все обороты можно посчитать в одном селекте.
Максимально убрать интерфейсные вызовы.
if CLIENT is not null then - не использовать переменные = наименованию типов/реквизитов.
Не использовать однобуквенные алиасы - их найти по тексту затруднительно. |
|
 |
mmm_kazan Участник со стажем
Вступление в Клуб: 28.03.2018
|
Вт Апр 10, 2018 15:02   |
|
Полезность: Нет оценки
|
Операция простая.
Отчет выводится на основании фильтров.
Подразделение, клиент, группа риска(внутренняя - доп.поле)
Интерфейсные вызовы лучше в переменные засунуть? |
|
 |
Volod Эксперт
Вступление в Клуб: 19.09.2007
|
Вт Апр 10, 2018 15:55   |
|
Полезность: Нет оценки
|
Интерфейсные вызовы нужно заменить на вычисление колонок в соответствующем селекте
r1.[C_ORG].[PARTNER].[NAME]
r1.[C_ORG].[RANGE].[VALUE]
c.[af_id].[MAIN_V_ID]
r.[C_ORG].[ALL_BOSS] is not null - тут правильно %size(1) > 0
if r.[C_ORG].[LINKS_OTHER] is not null - тут правильно %size(1) > 0
и смысл вообще проверять, если дальше select loop |
|
 |
Volod Эксперт
Вступление в Клуб: 19.09.2007
|
Вт Апр 10, 2018 16:39   |
|
Полезность: Нет оценки
|
Здесь могут тормоза - LEGAL_161P м.б. немаленькая таблица.
Есть же ссылка на клиента в BLOCK_ARR
Код: | for
(select l1(l1 : l1_id)
in ::[LEGAL_161P]
where l1.vo=1984365)
loop
if ::[LEGAL_161P].[Z134021099].get_payer_inn(l1.l1_id)=c.[c_inn] or ::[LEGAL_161P].[Z134021099].get_recip_inn(l1.l1_id)=c.[c_inn] then
c_Number_Doc_Ostanov_str := '6001. Код подозрительных операций.';
exit;
end if;
end loop; |
|
|
 |
mmm_kazan Участник со стажем
Вступление в Клуб: 28.03.2018
|
Вт Апр 10, 2018 17:30   |
|
Полезность: Нет оценки
|
Volod пишет: | Здесь могут тормоза - LEGAL_161P м.б. немаленькая таблица.
Есть же ссылка на клиента в BLOCK_ARR
Код: | for
(select l1(l1 : l1_id)
in ::[LEGAL_161P]
where l1.vo=1984365)
loop
if ::[LEGAL_161P].[Z134021099].get_payer_inn(l1.l1_id)=c.[c_inn] or ::[LEGAL_161P].[Z134021099].get_recip_inn(l1.l1_id)=c.[c_inn] then
c_Number_Doc_Ostanov_str := '6001. Код подозрительных операций.';
exit;
end if;
end loop; |
|
Там по одному клиенту только работает. Если выбран. По многим клиентам действительно долго. |
|
 |
mmm_kazan Участник со стажем
Вступление в Клуб: 28.03.2018
|
Вт Апр 10, 2018 17:32   |
|
Полезность: Нет оценки
|
Volod пишет: | Интерфейсные вызовы нужно заменить на вычисление колонок в соответствующем селекте
r1.[C_ORG].[PARTNER].[NAME]
r1.[C_ORG].[RANGE].[VALUE]
c.[af_id].[MAIN_V_ID]
r.[C_ORG].[ALL_BOSS] is not null - тут правильно %size(1) > 0
if r.[C_ORG].[LINKS_OTHER] is not null - тут правильно %size(1) > 0
и смысл вообще проверять, если дальше select loop |
А такой вариант интерфейсных вызовов может тормозить? Я считал что объект имею - к его свойствам быстро доступ происходит. |
|
 |
|