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

scelta dell'operatore di ottimizzazione delle query - cicli nidificati vs corrispondenza hash (o unione)

ASSOLUTAMENTE. Un hash match sarebbe un enorme miglioramento. La creazione dell'hash sulla tabella di 19.223 righe più piccola e l'analisi con la tabella di 65.991 righe più grande è un'operazione molto più piccola rispetto al ciclo nidificato che richiede 1.268.544.993 confronti di righe.

L'unico motivo per cui il server sceglierebbe i cicli nidificati è che ha sottovalutato gravemente il numero di righe coinvolte. Le tue tabelle contengono statistiche e, in caso affermativo, vengono aggiornate regolarmente? Le statistiche sono ciò che consente al server di scegliere buoni piani di esecuzione.

Se hai affrontato correttamente le statistiche e hai ancora un problema, potresti costringerlo a utilizzare un join HASH in questo modo:

SELECT *
FROM
   TableA A -- The smaller table
   LEFT HASH JOIN TableB B -- the larger table

Tieni presente che nel momento in cui lo fai, verrà forzato anche l'ordine di unione. Ciò significa che devi disporre correttamente tutti i tuoi tavoli in modo che il loro ordine di unione abbia un senso. In genere si esamina il piano di esecuzione che il server ha già e si modifica l'ordine delle tabelle nella query in modo che corrisponda. Se non hai familiarità con come farlo, le basi sono che ogni input "sinistro" viene prima e nei piani di esecuzione grafica, l'input sinistro è il inferiore uno. Un join complesso che coinvolge molte tabelle potrebbe dover raggruppare i join tra parentesi o utilizzare RIGHT JOIN per ottenere un piano di esecuzione ottimale (scambia gli input sinistro e destro, ma introduci la tabella nel punto corretto dell'ordine di unione).

In genere è meglio evitare di utilizzare i suggerimenti di unione e di forzare l'ordine di unione, quindi prima fai tutto il possibile! Potresti esaminare gli indici sulle tabelle, la frammentazione, la riduzione delle dimensioni delle colonne (come l'utilizzo di varchar invece di nvarchar dove Unicode non è richiesto) o suddividendo la query in parti (inserire prima una tabella temporanea, quindi unirla a quella).