Sto avendo un problema di prestazioni.Multipli INNER JOIN è troppo lento SQL SERVER
Ho creato una tabella che riceve dati da un file, faccio un BULK INSERT
. Quindi eseguo un SELECT
con più INNER JOIN
s (11 inner joins) da inserire in un'altra tabella con i dati corretti.
Quando eseguo questo SELECT
, ci vuole troppo tempo (più di un'ora) e quindi lo interrompo. La mia soluzione era quella di rompere questa query in 3, creando le tabelle @temp
. Con mia sorpresa, ci vogliono 3 minuti. Questo è quello che sto cercando di capire, PERCHÉ rompere la mia domanda in 3 è stato più veloce di una dichiarazione selezionata. Qui è la mia domanda:
SELECT t1.ReturnINT, t1.ReturnBIT, t2.ReturnINT, t3.ReturnINT, t5.ReturnINT, t1.ReturnDateTime
FROM t1
INNER JOIN t2
ON t2.my_column_varchar = t1.my_column_varchar
INNER JOIN t3
ON t3.my_column_number = t1.my_column_number AND t2.my_column_ID = t3.my_column_ID
INNER JOIN t4
ON t4.my_column_varchar = t1.my_column_varchar
INNER JOIN t5
ON t5.my_column_int = t1.my_column_int AND t5.my_column_int = t4.my_column_int AND t2.my_column_int = t5.my_column_int
INNER JOIN t6
ON t6.my_column_int = t5.my_column_int AND t6.my_column_int = t2.my_column_int
INNER JOIN t7
ON t7.my_column_int = t6.my_column_int
INNER JOIN t8
ON t8.my_column_int = t3.my_column_int AND t8.my_column_datetime = t1.my_column_datetime
INNER JOIN t9
ON t9.my_column_int = t3.my_column_int AND t8.my_column_datetime BETWEEN t9.my_column_datetime1 AND t9.datetime1 + t9.my_column_datetime2
INNER JOIN t10
ON t10.my_column_int = t9.my_column_int AND t10.my_column_int = t6.my_column_int
INNER JOIN t11
ON t11.my_column_int = t9.my_column_int AND t8.my_column_datetime = t11.my_column_datetime
---- ---- A CURA
non c'è dove la clausola, la mia domanda è esattamente come ho messo qui.
Ecco le mie ricerche interrotte, ho dimenticato di metterle qui. Funziona in 3 minuti.
DECLARE @temp TABLE (
<Some_columns>
)
INSERT INTO @temp
SELECT <My_Linked_Columns>
FROM t1
INNER JOIN t2
ON t2.my_column_varchar = t1.my_column_varchar
INNER JOIN t3
ON t3.my_column_number = t1.my_column_number AND t2.my_column_ID = t3.my_column_ID
INNER JOIN t4
ON t4.my_column_varchar = t1.my_column_varchar
INNER JOIN t5
ON t5.my_column_int = t1.my_column_int AND t5.my_column_int = t4.my_column_int AND t2.my_column_int = t5.my_column_int
DECLARE @temp2 TABLE(
<Some_Columns>
)
INSERT INTO @temp2
SELECT <More_Linked_Columns>
FROM @temp as temp
INNER JOIN t6
ON t6.my_column_int = temp.my_column_int AND t6.my_column_int = temp.my_column_int
INNER JOIN t7
ON t7.my_column_int = t6.my_column_int
INNER JOIN t8
ON t8.my_column_int = temp.my_column_int AND t8.my_column_datetime = temp.my_column_datetime
DECLARE @temp3 TABLE(
<Some_Columns>
)
INSERT INTO @temp3
SELECT <More_Linked_Columns>
FROM @temp2 AS temp2
INNER JOIN t9
ON t9.my_column_int = temp2.my_column_int AND temp2.my_column_datetime BETWEEN t9.my_column_datetime1 AND t9.datetime1 + t9.my_column_datetime2
INNER JOIN t10
ON t10.my_column_int = t9.my_column_int AND t10.my_column_int = temp2.my_column_int
INNER JOIN t11
ON t11.my_column_int = t9.my_column_int AND temp2.my_column_datetime = t11.my_column_datetime
SELECT <All_Final_Columns>
FROM @temp3
---- ---- modificato 3
Studiando altre cose che ho scoperto un problema nel piano di esecuzione. Ho un ciclo nidificato che stima 1 riga ma in realtà restituisce righe 1.204.014. Credo che il problema è proprio qui, ma non ho trovato il modo di risolvere questo problema senza rompere la mia domanda in 3 parti (ora so perché romperlo è più veloce hehehe)
motivi
Questo potrebbe essere un numero qualsiasi di cose. Potrebbe essere indicizzazione, potrebbe essere che tu abbia predicati non SAGGabili se esiste una clausola where, la lista potrebbe andare avanti e avanti. Senza alcuni dettagli reali c'è poco che nessuno può fare se non indovinare cosa sta facendo questo lento. –
Riduce le scelte di Optimizer per decidere l'ordine di join e il tipo di join –