2015-05-06 88 views
7

Qual è la differenza tra la clausola WITH e la sottoquery?Differenza tra clausola WITH e subquery?

1. WITH table_name as (...) 

2. select * 
    from (select curr from tableone t1 
      left join tabletwo t2 
       on (t1.empid = t2.empid) 
     ) as temp_table 

risposta

0

Forse nessuno. Oracle è capace di molte trasformazioni algebriche prima di ottimizzare effettivamente la query. Molto probabilmente entrambe le query saranno valutate allo stesso modo (avranno lo stesso piano di esecuzione).

18

La clausola WITH è per subquery factoring, noto anche come espressioni di tabella comuni o CTE:

Il CON QUERY_NAME clausola permette di assegnare un nome ad un blocco sottoquery. È quindi possibile fare riferimento al blocco di sottoquery in più posizioni nella query specificando nome_interrogazione. Oracle Database ottimizza la query trattando il nome della query come visualizzazione in linea o come tabella temporanea.

Nel tuo secondo esempio, quello che hai chiamato temp_table è una vista in linea, non una tabella temporanea.

In molti casi la scelta di quale utilizzare dipende dallo stile preferito e le CTE possono rendere il codice più leggibile in particolare con più livelli di sottoquery (le opinioni variano ovviamente). Se si fa riferimento solo al CTE/visualizzazione in linea, probabilmente non si noterà alcuna differenza nelle prestazioni e l'ottimizzatore potrebbe finire con lo stesso piano.

Sono particolarmente utili quando è necessario utilizzare la stessa sottoquery in più di un posto, ad esempio in un unione. È possibile estrarre una visualizzazione incorporata in un CTE in modo che il codice non venga ripetuto e consente all'ottimizzatore di materializzarlo se ritiene che sarebbe utile.

Ad esempio, questo esempio forzato:

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 

potrebbe essere riscritta a:

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 

La sottoquery non deve essere ripetuta. Più complicato è il codice ripetuto, più è vantaggioso dal punto di vista della manutenzione utilizzare un CTE. E più costoso è il subquery, maggiore è il beneficio delle prestazioni potrebbe vedere vedere l'uso di un CTE, anche se l'ottimizzatore di solito è abbastanza bravo a capire cosa stai facendo comunque.

+0

Grazie Alex. È utile. –