У меня проблема с производительностью оператора SELECT, который я использую в курсоре. В утверждении один из терминов в предложении SELECT
является дорогостоящим для оценки (это вызов процедуры PL / SQL, который довольно интенсивно обращается к базе данных). Однако предложения WHERE
и ORDER BY
просты.
Я ожидал, что Oracle сначала выполнит предложение WHERE
для определения набора записей, соответствующих запросу, затем выполнит предложение ORDER BY
, чтобы упорядочить их, и, наконец, оценит каждое из условий в предложении SELECT
, Поскольку я использую это утверждение в курсоре, из которого я затем извлекаю результаты, я ожидал, что дорогостоящая оценка члена SELECT
будет выполняться только по мере необходимости, когда каждый результат запрашивается из курсора.
Однако я обнаружил, что это не та последовательность, которую использует Oracle. Вместо этого он оценивает термины в предложении SELECT
для каждой записи, которая соответствует предложению WHERE, перед выполнением сортировки. Из-за этого процедура, вызываемая дорого, вызывается для каждого результата в наборе результатов, прежде чем из курсора будут возвращены какие-либо результаты.
Я хочу иметь возможность вывести первые результаты из курсора как можно быстрее. Может кто-нибудь сказать мне, как убедить Oracle не оценивать вызов процедуры в операторе SELECT до тех пор, пока не будет выполнена сортировка?
Все это, вероятно, проще описать в примере кода:
Учитывая таблицу example
со столбцами a
, b
, c
и d
, у меня есть такое утверждение:
select a, b, expensive_procedure(c)
from example
where <the_where_clause>
order by d;
При выполнении этого expensive_procedure()
вызывается для каждой записи, которая соответствует предложению WHERE
, даже если я открываю оператор как курсор и извлекаю из него только один результат.
Я пытался реструктурировать утверждение как:
select a, b, expensive_procedure(c)
from example, (select example2.rowid, ROWNUM
from example example2
where <the_where_clause>
order by d)
where example.rowid = example2.rowid;
Где присутствие ROWNUM
во внутреннем операторе SELECT
вынуждает Oracle сначала оценить его. Такая реструктуризация имеет желаемый выигрыш в производительности. К сожалению, это не всегда соответствует порядку, который требуется.
Просто чтобы прояснить, я знаю, что я не буду улучшать время, необходимое для возврата всего набора результатов. Я надеюсь улучшить время, необходимое для возврата первых нескольких результатов из заявления. Я хочу, чтобы время, затрачиваемое на курсор, повторялось, а не все прошло, пока не вернется первый результат.
Может ли какой-нибудь гуру Oracle сказать мне, как я могу убедить Oracle прекратить выполнение PL / SQL, пока это не понадобится?