ti vedo ora ho postato the plans. Solo fortuna del sorteggio.
La tua query effettiva è un 16 join tabella.
SELECT max(atDate1) AS AtDate1,
min(atDate2) AS AtDate2,
max(vtDate1) AS vtDate1,
min(vtDate2) AS vtDate2,
max(bgtDate1) AS bgtDate1,
min(bgtDate2) AS bgtDate2,
max(lftDate1) AS lftDate1,
min(lftDate2) AS lftDate2,
max(lgtDate1) AS lgtDate1,
min(lgtDate2) AS lgtDate2,
max(bltDate1) AS bltDate1,
min(bltDate2) AS bltDate2
FROM (SELECT TOP 100000 at.Date1 AS atDate1,
at.Date2 AS atDate2,
vt.Date1 AS vtDate1,
vt.Date2 AS vtDate2,
bgt.Date1 AS bgtDate1,
bgt.Date2 AS bgtDate2,
lft.Date1 AS lftDate1,
lft.Date2 AS lftDate2,
lgt.Date1 AS lgtDate1,
lgt.Date2 AS lgtDate2,
blt.Date1 AS bltDate1,
blt.Date2 AS bltDate2
FROM dbo.Tab1 a
INNER JOIN dbo.Tab2 at
ON a.id = at.Tab1Id
AND cast(Getdate() AS DATE) BETWEEN at.Date1 AND at.Date2
INNER JOIN dbo.Tab5 v
ON v.Tab1Id = a.Id
INNER JOIN dbo.Tab16 g
ON g.Tab5Id = v.Id
INNER JOIN dbo.Tab3 vt
ON v.id = vt.Tab5Id
AND cast(Getdate() AS DATE) BETWEEN vt.Date1 AND vt.Date2
LEFT OUTER JOIN dbo.Tab4 vk
ON v.id = vk.Tab5Id
LEFT OUTER JOIN dbo.VerkaufsTab3 vkt
ON vk.id = vkt.Tab4Id
LEFT OUTER JOIN dbo.Plu p
ON p.Tab4Id = vk.Id
LEFT OUTER JOIN dbo.Tab15 bg
ON bg.Tab5Id = v.Id
LEFT OUTER JOIN dbo.Tab7 bgt
ON bgt.Tab15Id = bg.Id
AND cast(Getdate() AS DATE) BETWEEN bgt.Date1 AND bgt.Date2
LEFT OUTER JOIN dbo.Tab11 b
ON b.Tab15Id = bg.Id
LEFT OUTER JOIN dbo.Tab14 lf
ON lf.Id = b.Id
LEFT OUTER JOIN dbo.Tab8 lft
ON lft.Tab14Id = lf.Id
AND cast(Getdate() AS DATE) BETWEEN lft.Date1 AND lft.Date2
LEFT OUTER JOIN dbo.Tab13 lg
ON lg.Id = b.Id
LEFT OUTER JOIN dbo.Tab9 lgt
ON lgt.Tab13Id = lg.Id
AND cast(Getdate() AS DATE) BETWEEN lgt.Date1 AND lgt.Date2
LEFT OUTER JOIN dbo.Tab10 bl
ON bl.Tab11Id = b.Id
LEFT OUTER JOIN dbo.Tab6 blt
ON blt.Tab10Id = bl.Id
AND cast(Getdate() AS DATE) BETWEEN blt.Date1 AND blt.Date2
WHERE a.Nummer = 223889) B
Su entrambi i piani di buoni e cattivi il piano di esecuzione mostra "La ragione per la risoluzione anticipata della Dichiarazione Optimization" come "Time Out".
I due piani hanno ordini di join leggermente diversi.
L'unica unirsi nei piani non soddisfatte da un indice cercare è che il Tab9
. Questo ha 63.926 righe.
I dettagli di indice mancanti nel piano di esecuzione suggeriscono di creare il seguente indice.
CREATE NONCLUSTERED INDEX [miising_index]
ON [dbo].[Tab9] ([Date1],[Date2])
INCLUDE ([Tab13Id])
La parte problematica del cattivo piano può essere visto chiaramente in SQL Plan Sentry Explorer
SQL Server stima che 1.349174 righe verranno restituiti dal precedente unisce entrano in join su Tab9
. Di conseguenza, i loop annidati vengono uniti come se fosse necessario eseguire la scansione nella tabella interna 1.349174 volte.
In effetti, 2600 righe vengono immesse in quel join, il che significa che esegue 2.600 scansioni complete di Tab9
(2.600 * 63.926 = 164.569.600 righe.)
Si dà il caso che sul buon piano il numero stimato di righe in arrivo al join sia 2.74319. Ciò è ancora errato di tre ordini di grandezza ma la stima leggermente aumentata significa che SQL Server preferisce invece un join hash. Un hash join solo fa un solo passaggio attraverso Tab9
Desidero in primo luogo provare ad aggiungere l'indice mancante su Tab9
.
Inoltre/invece si potrebbe provare ad aggiornare le statistiche su tutte le tabelle coinvolte (in particolare quelli con una data predicato come Tab2
Tab3
Tab7
Tab8
Tab6
) e vedere se questo va in qualche modo a correggere l'enorme discrepanza tra le righe previste e quelle effettive su la sinistra del piano.
Anche rompere la query in parti più piccole e materializzarle in tabelle temporanee con indici appropriati può essere d'aiuto. SQL Server può quindi utilizzare le statistiche su questi risultati parziali per prendere decisioni migliori per i join più avanti nel piano.
Solo come ultima risorsa considererei l'utilizzo di suggerimenti per le query per provare a forzare il piano con un hash join. Le opzioni disponibili sono l'avviso USE PLAN
, nel qual caso è necessario dettare esattamente il piano che si desidera includere tutti i tipi di join e gli ordini o dichiarando LEFT OUTER HASH JOIN tab9 ...
. Questa seconda opzione ha anche l'effetto collaterale di correggere tutti gli ordini di join nel piano. Entrambi significano che SQL Server sarà gravemente limitato è la sua capacità di regolare il piano con modifiche nella distribuzione dei dati.
Dovrai dare un'occhiata al piano di esecuzione per essere sicuro. È probabile che stia prendendo un percorso più efficiente con il TOP che senza. – Khan
Questo potrebbe essere causato da un problema di ottimizzazione. Potete fornire piani di esecuzione per entrambe le domande? –
Il modo migliore per fornire i piani di esecuzione è eseguirli in SSMS con l'opzione "Query -> Includi piano di esecuzione reale" abilitata, quindi caricare la versione XML in un sito come pastebin. Vedi [Come posso fornire un piano di esecuzione a qualcuno per l'analisi?] (Http://meta.dba.stackexchange.com/questions/796/how-do-i-provide-an-execution-plan-to-someone- for-analysis) per di più. –