WITH
klauzula dotyczy faktoringu podzapytania, znanego również jako wspólne wyrażenia tabelowe lub CTE:
Klauzula WITH nazwa_zapytania umożliwia przypisanie nazwy do bloku podzapytania. Następnie możesz odwołać się do bloku podzapytania w wielu miejscach w zapytaniu, określając nazwa_zapytania. Oracle Database optymalizuje zapytanie, traktując nazwę zapytania jako widok wbudowany lub jako tabelę tymczasową.
W drugim przykładzie to, co nazwałeś temp_table
jest wbudowanym widokiem, a nie tabelą tymczasową.
W wielu przypadkach wybór, którego chcesz użyć, sprowadza się do preferowanego stylu, a CTE może sprawić, że kod będzie bardziej czytelny, szczególnie w przypadku wielu poziomów podzapytań (opinie są oczywiście różne). Jeśli raz odwołasz się do widoku CTE/wbudowanego, prawdopodobnie nie zauważysz żadnej różnicy w wydajności, a optymalizator może otrzymać ten sam plan.
Są one jednak szczególnie przydatne, gdy musisz użyć tego samego podzapytania w więcej niż jednym miejscu, na przykład w unii. Możesz przeciągnąć widok wbudowany do CTE, aby kod się nie powtarzał i aby optymalizator mógł go zmaterializować, jeśli uzna to za korzystne.
Na przykład ten wymyślny przykład:
select curr from (
select curr from tableone t1
left join tabletwo t2 on (t1.empid = t2.empid)
) temp_table
where curr >= 0
union all
select -1 * curr from (
select curr from tableone t1
left join tabletwo t2 on (t1.empid = t2.empid)
) temp_table
where curr < 0
można przerobić na:
with temp_table as (
select curr from tableone t1
left join tabletwo t2 on (t1.empid = t2.empid)
)
select curr from temp_table
where curr >= 0
union all
select -1 * curr from temp_table
where curr < 0
Podzapytanie nie musi już być powtarzane. Im bardziej skomplikowany jest powtarzany kod, tym korzystniejsze z punktu widzenia konserwacji jest użycie CTE. A im droższe podzapytanie, tym większą możesz zwiększyć wydajność. widać po użyciu CTE, chociaż optymalizator jest zwykle całkiem dobry w ustalaniu, co i tak robisz.