Тривиальный ответ (весьма вероятное правильное предположение) - это отсутствующий индекс для FLOW(CONTRACT_ID)
.
Это приводит к FULL TABLE SCAN
при каждом вызове функции.
Обратите внимание, что в случае, если столбец CONTRACT_ID
не очень избирателен, вам может потребоваться добавить в функцию какой-либо другой столбец из предиката, используемого в запросе (например, REVERSAL_STATUS
).
Но вы можете сделать еще лучше - вам нужно только оставить позади курсора PL / SQL строка за строкой logik и ввести подход SQL .
Это решит две дополнительные проблемы , которые остаются после добавления индекса:
Контекст PL / SQL, который обходится дорого в случае большого количества вызовов функций
Вы реализовали ВНЕШНЕЕ СОЕДИНЕНИЕ с вопросом DIY
, что намного медленнее, чем в Oracle.
Какой вам нужен идентификатор, чтобы получить для каждого contract_id
из CONTRACT_TEMP
минимального EXPECTED_DT
из FLOW
, если существует, отфильтрованного с помощью предиката WHERE в функции .
Это можно сделать в два этапа:
1) Предварительный расчет для каждого CONTRACT_ID
минимального EXPECTED_DT
- см. Подзапрос ниже. Обратите внимание, что с помощью GROUP BY
вы рассчитываете результат для каждого контракта за один шаг.
2) LEFT OUTER JOIN
таблица CONTRACT_TEMP
с результатом 1)
Запрос - это эквивалентно вашему первоначальному запросу:
SELECT f.EXPECTED_DT
FROM CONTRACT_TEMP c
LEFT OUTER JOIN
(SELECT CONTRACT_ID, MIN(EXPECTED_DT) EXPECTED_DT
FROM FLOW
WHERE REVERSAL_STATUS = 4200
AND FLOW_TYPE IN(1003,1006,1027)
AND IS_CASH = 1
AND AMOUNT > 0
AND AMOUNT > NVL(AMT_MATCHED,0)
GROUP BY CONTRACT_ID) f
on c.CONTRACT_ID = f.CONTRACT_ID