2012-04-11 9 views
6

Se si dispone di un'istruzione select con una funzione scalare utilizzata in vari calcoli, la funzione scalare ottiene chiamato più volte? Se lo fa, c'è un modo per ottimizzare questo in modo da chiamare solo la funzione una volta per selezionare, come nella mia vera query verrà chiamato migliaia di volte, X 6 volte per selezionare.Il richiamo di una funzione scalare in un'istruzione select più volte esegue la funzione più volte e come spostarsi in caso affermativo

Ad esempio:

SELECT 
[dbo].[fn_Days](@Account) + u.[DayRate], 
[dbo].[fn_Days](@Account)/u.[WorkDays] 
FROM [dbo].[tblUnit] u 

Tutti fn_days fa è restituire un int di giorni di lavoro.

+0

destro mi rendo conto che funziona per ogni riga, ma dal momento che è stato eseguito 2 volte all'interno della stessa riga, in qualche modo potuto utilizzare lo stesso valore in modo non devo eseguire più volte per riga? – mameesh

+0

Notato così come hai postato il tuo commento. Potrebbe, in teoria, memorizzare il valore, ma dubito che lo faccia. Un modo approssimativo per capirlo potrebbe essere quello di creare una funzione che impiega volutamente molto tempo per essere eseguita e quindi chiamarla una volta una query e due volte in una query e confrontare i tempi di esecuzione. – Corbin

+0

Vedere che cos'è il piano di query se si unisce a un set che ha già il risultato della funzione come colonna. –

risposta

10

Sì, lo scalare viene chiamato più volte nel modo in cui è stato codificato. Un modo per farlo funzionare sarebbe quello di avvolgerlo in una sottoquery come questo: fn_Days

SELECT t.[days] + t.[DayRate], 
     t.[days]/t.[WorkDays] 
FROM (
    SELECT 
    [dbo].[fn_Days](@Account) as days, 
    u.[DayRate], 
    u.[WorkDays] 
    FROM [dbo].[tblUnit] u) as t 

questo modo solo viene chiamato una volta per ogni fila, piuttosto che due volte, o sei volte, come lei ha citato.

Spero che questo aiuti.

2

Le funzioni sono deterministiche, il che significa che restituirà sempre lo stesso valore per un determinato parametro. Si sta utilizzando una variabile come parametro in modo da poter richiamare la funzione una volta prima dell'esecuzione della query e utilizzare il risultato nella query anziché chiamare la funzione.

DECLARE @Days int 
SET @Days = [dbo].[fn_Days](@Account) 

SELECT 
    @Days + u.[DayRate], 
    @Days/u.[WorkDays] 
FROM [dbo].[tblUnit] u 
Problemi correlati