У меня нет ваших таблиц и ваших данных, поэтому я могу только догадываться о нескольких вещах, которые будут вас тормозить.
Во-первых, запрос, используемый в вашем курсоре, имеет предложение ORDER BY
в этом.Если этот запрос возвращает много строк, Oracle должен извлечь их все и отсортировать все, прежде чем он сможет вернуть первую строку.Если этот запрос обычно возвращает много результатов, и вам не требуется его возвращать отсортированные результаты, вы можете обнаружить, что ваш блок PL / SQL немного ускоряется, если вы уроните ORDER BY
.Таким образом, вы можете начать получать результаты из курсора без необходимости извлекать все результаты, сохранять их где-то и сначала сортировать.
Во-вторых, ниже приведено предложение WHERE
, используемое в вашем INSERT INTO ... SELECT ...
и DELETE FROM ...
операторы:
where substr(Digits, 1, 2) = substr(v_MDLDigits, 1, 2)
and instr(Digits, v_MDLDigits) = 1
and v_mdlEffectiveDate <= effectivedate
and (v_mdlExpDate > effectivedate or v_mdlExpDate is null);
Я не понимаю, как Oracle может эффективно использовать индексы с любым из этих условий.Поэтому каждый раз приходится выполнять полное сканирование таблицы.
Последние два условия кажутся разумными, и с ними мало что можно сделать.Я хотел бы сосредоточиться на первых двух условиях, так как я думаю, что есть больше возможностей для их улучшения.
Вторым из четырех условий является
instr(Digits, v_MDLDigits) = 1
Это условие выполняется, если и толькоесли Digits
начинается с содержимого v_MDLDigits
.Лучшим способом написания этого будет
Digits LIKE v_MDLDigits || '%'
. Преимущество использования LIKE
в этой ситуации вместо INSTR
состоит в том, что Oracle может использовать индексы при использовании LIKE
.Если у вас есть индекс по столбцу Digits
, Oracle сможет использовать его с этим запросом.Затем Oracle сможет сосредоточиться на тех строках, которые начинаются с цифр в v_MDLDigits
, вместо того, чтобы выполнять полное сканирование таблицы.
Первое из четырех условий:
substr(Digits, 1, 2) = substr(v_MDLDigits, 1, 2)
Если v_MDLDigits
имеет длину не менее 2, а все записи в столбцах Digits
также имеют длину не менее 2, то это условие является избыточным, поскольку оно подразумевается предыдущим, на которое мы смотрели.
Я не уверен, почему у вас было бы такое состояние.Единственная причина, по которой я могу подумать, почему у вас может быть это состояние, - это если у вас функциональный индекс на substr(Digits, 1, 2)
.Если нет, я бы соблазнился полностью удалить это substr
условие.
Я не думаю, что курсор - это то, что заставляет эту процедуру выполняться медленно, и я не знаю ни одного известного утверждения, которое можно вставить водну таблицу и удалить из другой.Чтобы ускорить эту процедуру, я думаю, вам просто нужно немного настроить запросы.