10

Perché la Query versione 2 è molto più veloce?Perché una query viene eseguita molto più rapidamente quando memorizzo (manualmente) i risultati di una funzione con valori di tabella in una tabella temporanea?

Sospetto che il DB Engine stia chiamando la funzione con valori di tabella "GetUsageStatistic" più volte, quindi c'è un modo per dire al motore che "GetUsageStatistic" è deterministico e dovrebbe essere chiamato una sola volta?

Query versione 1

--Takes ~10 minutes 
select * 
from RosterLevel r 
left join GetUsageStatistics(@mindate, @maxdate) usage on r.UserID = usage.UserID; 

Query versione 2

--Takes ~10 seconds 
select * into #usage from GetUsageStatistics(@mindate, @maxdate); 
select * 
from RosterLevel r 
left join #usage on r.UserID = #usage.UserID; 
+0

Che aspetto ha il corpo di 'GetUsageStatistics'? È una singola query o più query che portano a un singolo set di risultati? –

+0

GetUsageStatistics è una funzione a valore di tabella inline (ITVF), che seleziona da GetWeeklyUsage, che è esso stesso un ITVF che seleziona da GetDailyUsage (anche un ITVF). È fondamentalmente una semplice catena di ITVF deterministici che restituiscono ciascun livello di risultati aggregati con le funzioni SUM, AVG e COUNT nelle colonne di output. – Triynko

+0

@Triynko: vale sicuramente la pena ottenere piani di esecuzione effettivi per entrambe le query e confrontarli per verificare se la tua esecuzione a più riprese della teoria TVF sia corretta. –

risposta

1

Come accennato nei commenti, la risposta migliore è quello di analizzare tutto ciò che piano di esecuzione è sputare. Escludendo ciò, probabilmente la tua intuizione è giusta, ma a prescindere da qualsiasi tentativo di memorizzazione automatica della cache da parte di SQL Server, non mi viene in mente il modo di suggerire le query che puoi fornire per indicare che la funzione è deterministica, ma puoi provare alcune cose citate nello Query Hints MSDN page. I miei primi test probabilmente disegnerebbero su Table Hints.

+0

Il tag "SQL" è un tag Microsoft? – Tim

+1

@ Tim: No. Eppure molte persone sembrano scambiarlo per esserlo, in realtà. Un altro motivo per supporre che SQL Server potrebbe essere che lo script dell'OP è ovviamente T-SQL (da "#" -names). Ma probabilmente la vera ragione è che l'OP ha menzionato SSMS in uno dei loro commenti. –

+0

@Tim: @Andriy tipo di diritto - "ovvio" è soggetto però, in quanto si applica solo alle persone che sanno già come si presenta TSQL e che SSMS è MS. Ma a parte questo snobismo :-), hai ragione, questa non è una domanda SQL generale, è una domanda TSQL, e questo fa la differenza per quanto riguarda chi può rispondere, e chi sarebbe interessato a cercarlo/leggere in primo luogo. – Chains

0

Se si utilizza la funzione nel primo esempio, viene chiamata più volte, una volta per ogni record nella tabella RosterLevel. Restituisce una tabella (potenzialmente) diversa ogni volta, a seconda del campo di join.

Se si utilizza la funzione nel secondo esempio, viene chiamata solo una volta. Da lì, la variabile table è in memoria, e non devi fare una lettura più e più volte.