it-swarm.it

SQL Server Join / dove ordine di elaborazione

Dopo aver letto query SQL lenta, non so come ottimizzare , mi ha fatto pensare alle prestazioni generali delle query. Sicuramente, abbiamo bisogno che i risultati della prima tabella (quando vengono unite altre tabelle) siano i più piccoli possibili prima di unirci (join interni per questa domanda) al fine di rendere le nostre query un po 'più veloci.

Esempio, se questo:

SELECT *
FROM   ( SELECT * FROM table1 WHERE col = @val ) t
INNER JOIN table2 ON col = col2

Sii migliore/più veloce di:

SELECT *
FROM table1
INNER JOIN table2 ON col = col2
WHERE table1.col = @val

La mia teoria è la seguente (questa potrebbe non essere l'implementazione corretta, sto cercando di ricordare da un libro interno di SQL Server 2008 che ho letto (MSFT Press)):

  1. Il processore di query ottiene prima la tabella di sinistra (tabella1)
  2. Unisce la seconda tabella (tabella2) e forma un prodotto cartesiano prima di filtrare le righe necessarie (se applicabile)
  3. Quindi esegue le clausole WHERE, ORDER BY, GROUP BY, HAVING con l'ultima istruzione SEELCT.

Quindi, se nell'istruzione n. 1 sopra, la tabella è più piccola, il motore SQL ha meno lavoro da fare quando si formano i prodotti cartesiani. Quindi quando si raggiunge l'istruzione where, si ottiene un set di risultati ridotto da cui filtrare in memoria.

Potrei essere così lontano dal segno che è irreale. Come ho detto, è una teoria.

I vostri pensieri?

Nota : Ho appena pensato a questa domanda e non ho ancora avuto la possibilità di eseguire alcun test da solo.

Nota 2 : Taggato come SQL Server perché non lo so nulla sull'implementazione di MySql ecc. libero di rispondere/commentare comunque

18
Stuart Blackler

L'elaborazione logica di una query è attiva MSDN (scritto dal team di Microsoft SQL Server, non da terze parti)

1. FROM
2. ON
3. JOIN
4. WHERE
5. GROUP BY
6. WITH CUBE or WITH ROLLUP
7. HAVING
8. SELECT
9. DISTINCT
10. ORDER BY
11. TOP

Segue una tabella derivata, quindi la query esterna lo fa di nuovo, ecc. Ecc

Questo è logico sebbene: non effettivo . Indipendentemente dal modo in cui lo fa SQL Server, queste semantiche sono onorate alla lettera. Il "reale" è determinato dallo Strumento per ottimizzare le query (QO) ed eviti il ​​prodotto intermedio di cartesione che hai citato.

Vale la pena ricordare che SQL è dichiarativo: dici "cosa" non "come" come faresti per una programmazione procedurale/imperativa (Java, .net). Quindi dire "questo accade prima" è sbagliato in molti casi (ad es. Ipotesi di corto circuito o ordine L-to-R DOVE)

Nel tuo caso sopra, il QO genererà lo stesso piano, non importa come sia strutturato perché è una query semplice.

Tuttavia, il QO è basato sui costi e per una query complessa potrebbero essere necessarie 2 settimane per generare il piano ideale. Quindi fa "abbastanza bene" che in realtà non lo è.

Quindi il tuo primo caso può aiutare l'ottimizzatore a trovare un piano migliore perché l'ordine logico di elaborazione è diverso per le 2 query. Ma potrebbe non farlo.

Ho usato questo trucco su SQL Server 2000 per ottenere un miglioramento delle prestazioni della velocità 60x sulle query di reporting. Man mano che il QO migliora versione per versione, migliora nel risolvere queste cose.

E il libro che hai citato: c'è qualche disputa al riguardo
Vedi SO e i collegamenti successivi: https://stackoverflow.com/q/3270338/27535

16
gbn

Una query SQL non è di natura procedurale, non esiste un'elaborazione dall'alto verso il basso degli operatori di join. L'ordinamento delle tabelle nelle query di esempio non ha alcuna influenza sul piano di esecuzione poiché sono logicamente equivalenti e genereranno esattamente lo stesso piano.

Hai valutato due delle opzioni che query optimizer potrebbe prendere in considerazione quando si genera un piano per questa query. Il fattore principale che influenza la scelta del piano è statistiche per le tabelle coinvolte e costi associati alle scelte dell'operatore in tutti i piani candidati.

Un join a due tabelle molto semplice come il tuo esempio potrebbe essere soddisfatto con una qualsiasi delle centinaia di piani di esecuzione diversi. L'ottimizzatore decide quale sarà il modo migliore per rispondere alla tua domanda confrontando i costi di questi piani.

A volte sbaglia e puoi aiutarlo a fare scelte migliori attraverso una migliore indicizzazione, mantenendo le statistiche aggiornate e applicando suggerimenti. In casi molto rari, potresti voler forzare l'ordine di esecuzione usando il suggerimento FORCE ORDER, ma dovrebbe essere usato con parsimonia. È un martello rompere un dado, l'ottimizzatore di solito può essere preso in giro per generare piani migliori fornendogli informazioni migliori.

6