Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Perché CTE (Common Table Expressions) in alcuni casi rallenta le query rispetto alle tabelle temporanee in SQL Server

La risposta è semplice.

SQL Server non materializza CTE. Li integra, come puoi vedere dai piani di esecuzione.

Altri DBMS possono implementarlo in modo diverso, un esempio ben noto è Postgres, che materializza CTE (in pratica crea tabelle temporanee per CTE dietro il cofano).

Se la materializzazione esplicita dei risultati intermedi in tabelle temporanee esplicite è più veloce, dipende dalla query.

Nelle query complesse, il sovraccarico di scrittura e lettura di dati intermedi in tabelle temporanee può essere compensato da piani di esecuzione più semplici e più efficienti che l'ottimizzatore è in grado di generare.

D'altra parte, in Postgres CTE è un "recinto di ottimizzazione" e il motore non può spingere i predicati oltre il confine CTE.

A volte un modo è migliore, a volte un altro. Una volta che la complessità della query cresce oltre una certa soglia, un ottimizzatore non può analizzare tutti i modi possibili per elaborare i dati e deve accontentarsi di qualcosa. Ad esempio, l'ordine in cui unire le tabelle. Il numero di permutazioni cresce esponenzialmente con il numero di tabelle tra cui scegliere. Optimiser ha un tempo limitato per generare un piano, quindi potrebbe fare una scelta sbagliata quando tutti i CTE sono in linea. Quando suddividi manualmente una query complessa in query più piccole e più semplici, devi capire cosa stai facendo, ma l'ottimizzatore ha maggiori possibilità di generare un buon piano per ogni query semplice.