2010-01-20 18 views
7

Dire per esempio che sto entrare su un tavolo numero per eseguire alcune operazioni tra due date in una sottoquery, in questo modo:In che modo Dateadd influisce sulle prestazioni di una query SQL?

select n 
     ,(select avg(col1) 
      from table1 
     where timestamp between dateadd(minute, 15*n, @ArbitraryDate) 
          and dateadd(minute, 15*(n+1), @ArbitraryDate)) 
    from numbers 
where n < 1200 

Sarebbe la query eseguire meglio se io, per esempio, ha costruito la data da VARCHAR concatenare di usare la funzione dateadd?

+0

n è un campo int (o smallint, qualunque) in table1? –

+0

@Patrick Karcher, n è un int dalla tabella [numero]. – Daniel

+0

MA hai bisogno di mostrarci la struttura di table1 – HLGEM

risposta

4

Mantenere i dati nel formato datetime utilizzando DATEADD è più probabile che sia questa domanda più veloce

Check: (! Non mi) Most efficient way in SQL Server to get date from date+time?

La risposta accettata dimostra DATEADD su conversioni di stringhe. Ne ho visto un altro troppi anni fa che mostrava lo stesso

+0

Questo è esattamente il tipo di risposta che speravo. +1 a te per averlo trovato e +1 a Tomas per il grande punto di riferimento. Grazie! – Daniel

3

NON andrei con concatenare varchars.

DateAdd sarà più performace rispetto alla contatenazione di stringhe e trasmetterà a DATETIME.

Come sempre, la soluzione migliore è quella di profilare le 2 opzioni e determinare il risultato migliore, in quanto non è specificato alcun DB.

+0

Qual è la ragione di questo? – Daniel

4

Fate attenzione con tra e date, dare un'occhiata a How Does Between Work With Dates In SQL Server?

una volta ho optmized una query per eseguire da più di 24 ore a 36 secondi. Basta non usare le funzioni di data o le conversioni sulla colonna, vedi qui: Only In A Database Can You Get 1000% + Improvement By Changing A Few Lines Of Code

per vedere quale query funziona meglio, eseguire entrambe le query e guardare i piani di esecuzione, è anche possibile utilizzare le statistiche io e le statistiche per ottenere quanti leggi e il tempo necessario per eseguire le query

+0

Grazie per l'avviso su "tra". Vedo che otterrei qualche sovrapposizione. – Daniel

2

Fintanto che i calcoli dei predicati non includono riferimenti alle colonne della tabella che stai interrogando, il tuo approccio non dovrebbe avere importanza in entrambi i casi (vai per chiarezza).

Se si desidera includere qualcosa nel calcolo Table1, tuttavia, fare attenzione alle scansioni di tabelle o alle scansioni dell'indice in quanto potrebbe non essere più sargable.

In ogni caso, controllare (o inviare!) Il execution plan per confermare.

2

Perché dovresti utilizzare una sottoquery correlata per iniziare? Questo ti rallenterà molto di più di dateadd. Sono come i cursori, lavorano fila per fila. Qualcosa come questo funziona?

select n.n , avgcol1 
    from numbers n 
    left outer join 
     (
     select avg(col1) as avgcol1, n 
     from table1 
     where timestamp between dateadd(minute, 15*n, @ArbitraryDate) 
      and dateadd(minute, 15*(n+1), @ArbitraryDate) 
     Group by n 
     ) t 
    on n.n = t.n 
    where n < 1200 
+0

Questa è una buona idea. Il problema è che table1 non è enumerata (o necessariamente enumerabile). – Daniel

+0

Mi sto prendendo a calci per non averlo visto. Ottimo punto. –

+0

Ho sostituito inner join con left outer, in modo che questa query sia equivalente a quella originale. –

3

molto probabilmente non ci saranno differenze in un modo o nell'altro. vorrei correre questo:

SET STATISTICS IO ON; 
SET STATISTICS TIME ON; 

seguito da entrambe le varianti della tua ricerca, in modo che si vede e confrontare i costi di esecuzione reali.

+0

Grazie per questo suggerimento pratico – Daniel

Problemi correlati