Ниже Query требуется много времени для выполнения, и этот запрос необходимо оптимизировать. Я пытаюсь оптимизировать запрос, но мне нужно больше улучшений.
Я работаю со скалярным подзапросом с группой by, чтобы получить количество записей в каждом area_code
. Итак, я использовал запрос ниже с подзапросом, который я пытался с соединением, но не могу получить требуемый результат.
SELECT int.AREA_CODE, mc.DESCRIPTION, (SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE MA_TYPE IN ('MAPAA')
AND a.AREA_CODE = int.AREA_CODE
) "F_Allocate", (SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE MA_TYPE IN ('MAPS')
AND a.AREA_CODE = int.AREA_CODE
) "F_Manual", (SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE MA_TYPE IN ('MAPS', 'MAPAA')
AND a.AREA_CODE = int.AREA_CODE
) "F_Total", ROUND(
(SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE MA_TYPE IN ('MAPAA')
AND a.AREA_CODE = int.AREA_CODE
) /
(SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE MA_TYPE IN ('MAPS', 'MAPAA')
AND a.AREA_CODE = int.AREA_CODE
)) *100
||' %' AS "F_PER_Allocation", (SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE BILLING_TYPE IN ('CBFAA')
AND a.AREA_CODE = int.AREA_CODE
) "D_Allocation", (SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE BILLING_TYPE IN ('CBFA')
AND a.AREA_CODE = int.AREA_CODE
) "D_Manual", (SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE BILLING_TYPE IN ('CBFA', 'CBFAA')
AND a.AREA_CODE = int.AREA_CODE
) "D_Total", ROUND(
(SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE BILLING_TYPE IN ('CBFAA')
AND a.AREA_CODE = int.AREA_CODE
) /
(SELECT COUNT(*)
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE BILLING_TYPE IN ('CBFA', 'CBFAA')
AND a.AREA_CODE = int.AREA_CODE
))*100
||' %' AS "D_per_Allocation"
FROM INTIMA_TB INT
JOIN REIMB_TB rem
ON int.INTIMA_KEY = rem.INTIMA_KEY
JOIN MAS_CPU_CODE mc
ON mc.CPU_KEY = int.AREA_CODE
WHERE TRUNC(rem.CREATED_DATE) = TRUNC(SYSDATE-3)
GROUP BY int.AREA_CODE, mc.DESCRIPTION;
3 ответа
Все ваши подсчетные запросы относились к коду области и убивали каждое соединение для каждого скаляра, а затем каждый раз снова при окончательном соединении.
Я сделал один предварительный запрос из вашего согласованного СОЕДИНЕНИЯ между таблицами INTIMA_TB и REIMB_TB, но также добавил окончательное соединение на основе MAS_CPU_CODE в пределах того же кода области. Возможно, вам придется это изменить, но не думайте.
Внутренний запрос просматривает только те записи, которые соответствуют вашему «MA_TYPE» или «BILLING_TYPE», поскольку это все, что было засчитано. Каждое отдельное суммирование (сгруппированное по коду зоны) представляет собой случай / когда соответствующего состояния. Таким образом, полный внутренний запрос будет представлять собой одну строку для каждого кода области с каждым из отдельных агрегатов.
Теперь вы можете использовать каждый агрегированный столбец предварительного запроса (псевдоним PQ) в качестве последних столбцов во внешнем запросе. Образец ниже должен ЗНАЧИТЕЛЬНО помочь сократить время обработки.
select
PQ.Area_Code,
PQ.F_Allocate,
PQ.F_Manual,
PQ.F_Total,
round( PQ.F_Allocate / PQ.F_Total ) * 100 || ' %' AS F_PER_Allocation,
PQ.D_Allocation,
PQ.D_Manual,
PQ.D_Total,
round( PQ.D_Allocation / PQ.D_Total ) * 100 || ' %' AS D_PER_Allocation
from
(select
i.area_code,
sum( case when i.ma_type = 'MAPAA' then 1 else 0 end ) F_Allocate,
sum( case when i.ma_type = 'MAPS' then 1 else 0 end ) F_Manual,
sum( case when i.ma_type in ( 'MAPAA', 'MAPS' ) then 1 else 0 end ) F_Total,
sum( case when i.billing_type = 'CBFAA' then 1 else 0 end ) D_Allocation,
sum( case when i.billing_type = 'CBFA' then 1 else 0 end ) D_Manual,
sum( case when i.billing_type in ( 'CBFAA', 'CBFA' ) then 1 else 0 end ) D_Total,
from
INTIMA_TB i
JOIN REIMB_TB r
ON a.INTIMA_KEY = b.INTIMA_KEY
JOIN MAS_CPU_CODE mc
ON i.AREA_CODE = mc.CPU_KEY
where
i.ma_type in ( 'MAPAA', 'MAPS' )
OR i.billing_type in ( 'CBFAA', 'CBFA' )
group by
i.area_code ) PQ
Единственное, что может потребоваться изменить, - это ссылка на псевдоним «ma_type» и «billing_type» из соответствующего псевдонима «i» или «r». Ваш исходный запрос не соответствовал таблице, на которую ссылаются эти столбцы, поэтому может потребоваться корректировка в каждом из предложений SUM () и WHERE соответственно.
Замените все внутренние SELECT
на соответствующие JOIN
на ваших таблицах. В опубликованном запросе внутренние SELECT
будут выполняться для каждой очень тяжелой строки. Перемещение его для объединения в таблицы приведет к однократному выполнению запроса, а затем выполнению правильного сопоставления между таблицами. Показан пример для одной из таблиц:
...
FROM INTIMA_TB INT
JOIN REIMB_TB rem
ON int.INTIMA_KEY = rem.INTIMA_KEY
JOIN MAS_CPU_CODE mc
ON mc.CPU_KEY = int.AREA_CODE
LEFT JOIN
(SELECT COUNT(*), a.AREA_CODE
FROM INTIMA_TB a
JOIN REIMB_TB b
ON a.INTIMA_KEY = b.INTIMA_KEY
WHERE MA_TYPE IN ('MAPAA')
GROUP BY a.AREA_CODE
) "F_Allocate" on F_Allocate.AREA_CODE = int.AREA_CODE
...
Я предлагаю объединить таблицы напрямую и избегать подзапроса , потому что компилятор сначала прочитает внутренний запрос , а затем внешний запрос и у вас их так много, что это сделало его таким тяжелым.
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.