Domanda

Sto cercando di ottimizzare alcuni orrendamente complesse query SQL perché ci vuole troppo tempo per terminare.

In mie domande, ho creato in modo dinamico istruzioni SQL con un sacco di le stesse funzioni, così ho creato una tabella temporanea in cui ogni funzione viene chiamata solo una volta, invece di molte, molte volte - questo taglio il mio tempo di esecuzione per 3/4.

Quindi la mia domanda è, posso aspettare di vedere molta differenza se dire, 1.000 calcoli DateDiff sono ridotte a 100?

EDIT: La query è simile al seguente:

SELECT DISTINCT M.MID, M.RE FROM #TEMP INNER JOIN M ON #TEMP.MID=M.MID 
WHERE ( #TEMP.Property1=1 ) AND 
DATEDIFF( year, M.DOB, @date2 ) >= 15  AND  DATEDIFF( year, M.DOB, @date2 ) <= 17 

dove questi vengono generati dinamicamente come stringhe (messi insieme in pezzi) e quindi eseguito in modo che i vari parametri possono essere modificati lungo ciascuna iterazione - principalmente le ultime righe, contenente tutti i tipi di query DATEDIFF

.

Ci sono circa 420 query come questo, dove queste datediffs vengono calcolati in questo modo. So che li posso tirare in una tabella temporanea facilmente (1.000 datediffs diventa 50) - ma ne vale la pena, ce la farà alcuna differenza in pochi secondi? Spero in un miglioramento meglio che in decimi di secondo.

È stato utile?

Soluzione

Dipende da quello che stai facendo per essere onesti per quanto riguarda la portata del calo di prestazioni.

Ad esempio, se si utilizza DATEDIFF (o qualsiasi altra funzione) all'interno di una clausola WHERE, allora questa sarà una causa di peggiore performance in quanto impedisce un indice utilizzato su quella colonna.

es. esempio di base, trovare tutti i record nel 2009

WHERE DATEDIFF(yyyy, DateColumn, '2009-01-01') = 0

non sarebbe fare buon uso di un indice DateColumn. Considerando che una soluzione migliore, fornendo un uso ottimale indice sarebbe:

WHERE DateColumn >= '2009-01-01' AND DateColumn < '2010-01-01'

I recentemente bloggato su la differenza questo fa (con statistiche di performance / confronti del piano di esecuzione), se siete interessati.

Questo sarebbe più costoso di dire tornare DATEDIFF come una colonna nel set di risultati.

Vorrei iniziare identificando le singole query che stanno prendendo più tempo. Verificare i piani di esecuzione per vedere dove sta il problema e sintonizzare da lì.

Modifica Secondo l'esempio di query che hai dato, ecco un approccio che si potrebbe provare a rimuovere l'uso del DATEDIFF all'interno della clausola WHERE. Esempio di base per trovare tutti coloro che hanno 10 anni in una certa data - I pensare la matematica è giusto, ma si ottiene l'idea comunque! Abbiamo dato un test rapido, e sembra che vada bene. Dovrebbe essere abbastanza facile da adattare al vostro scenario. Se si vuole trovare persone tra (per esempio) di 15 e 17 anni in una determinata data, allora questo è possibile anche con questo approccio.

-- Assuming @Date2 is set to the date at which you want to calculate someone's age 
DECLARE @AgeAtDate INTEGER
SET @AgeAtDate = 10  

DECLARE @BornFrom DATETIME
DECLARE @BornUntil DATETIME
SELECT @BornFrom = DATEADD(yyyy, -(@AgeAtDate + 1), @Date2)
SELECT @BornUntil = DATEADD(yyyy, -@AgeAtDate , @Date2)

SELECT DOB
FROM YourTable
WHERE DOB > @BornFrom AND DOB <= @BornUntil

Una nota importante da aggiungere, è per caculates età da DOB, questo approccio è più accurato. Il tuo attuale implementazione richiede solo l'anno di nascita in considerazione, non il giorno stesso (ad esempio, qualcuno nato il 1 dicembre 2009 avrebbe mostrato come 1 anno di età il 1 gennaio 2010, quando non sono 1 fino 1 dicembre 2010).

Spero che questo aiuti.

Altri suggerimenti

DATEDIFF è abbastanza efficiente rispetto ad altri metodi di manipolazione dei valori datetime, come stringhe. ( vedono questo SO rispondere ) .

In questo caso, sembra che tu andare più e più volte gli stessi dati, che rischia più costoso di utilizzare una tabella temporanea. Ad esempio, verranno generate le statistiche.

Una cosa che si potrebbe essere in grado fare per migliorare le prestazioni potrebbe essere quella di mettere un indice sulla tabella temporanea su MID.

Controlla il tuo piano di esecuzione per vedere se aiuta (può dipendere dal numero di righe della tabella temporanea).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top