Ниже 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;
0
Nvr 4 Фев 2021 в 08:19

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 соответственно.

1
DRapp 4 Фев 2021 в 07:36

Замените все внутренние 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
...
0
Neo 4 Фев 2021 в 06:27

Я предлагаю объединить таблицы напрямую и избегать подзапроса , потому что компилятор сначала прочитает внутренний запрос , а затем внешний запрос и у вас их так много, что это сделало его таким тяжелым.

0
AminGolmahalle 4 Фев 2021 в 15:13
66039762