У меня есть запрос Oracle длиной более 1000 строк. Разрушение и / или использование хранимых процедур здесь не вариант. Я собираюсь сделать это еще длиннее. Какой из них имеет лучшую производительность? Я считаю, что версию WITH легче читать.
/* subselect */
select col01
,col02
from (
select case col01 when 'X' then 1 else 2 end col01
,case col02 when 'Y' then 3 else 4 end col02
from (
select upper(col01) col01
,upper(col02) col02
from (
select 'x' as col01
,'y' as col02
from dual
)
)
)
;
---------------------------------------
/* with statement */
with qry01 as (
select 'x' as col01
,'y' as col02
from dual
)
,qry02 as (
select upper(col01) col01
,upper(col02) col02
from qry01
)
,qry03 as (
select case col01 when 'X' then 1 else 2 end col01
,case col02 when 'Y' then 3 else 4 end col02
from qry02
)
select col01
,col02
from qry03
;
Вы не можете определить производительность запроса, глядя на него или спрашивая в Интернете; единственный способ узнать наверняка - это проверить. Думаю, это тоже не ваши настоящие вопросы.
Спасибо @mustaccio. Эта упрощенная версия очень упрощена. Я просто искал предложения, прежде чем потратить часы, чтобы преобразовать одно в другое.


Я также считаю, что выражение CTE WITH легче читать. Кроме того, есть причины предпочесть его.
/*+ MATERIALIZE */)Я считаю, что второй момент также верен для подзапроса без CTE.
@trincot, не знаю, вроде бы не так понятно: Материализовать подзапрос без использования предложения with - не путайте "материализацию" с "запросом на слияние"
Я не говорю о принудительной части (не говоря уже о «запросе на слияние»), а о «Оптимизаторе Oracle может ...». Я верю, что может.
Производительность должна быть практически такой же. Оптимизатор Oracle определяет лучший план запроса. Он может быть немного более гибким с CTE (позволяя материализацию), но это не имеет значения, если CTE упоминается только один раз.