2010-09-14 9 views
6

Ho una domanda, che è velocissima in SQL Server Management Studio e super lento quando viene eseguito sotto sp_executesql.Piani di SQL Server sp_executesql e l'esecuzione

È questo a che fare con la memorizzazione nella cache di piani di esecuzione non accadono quando viene eseguito sotto spExecuteSQL?

+7

Mi chiedo quando il "muto sp_executesql non memorizza i piani" il mito morirà mai - leggi [La maledizione e le benedizioni di SQL dinamico] (http://www.sommarskog.se/dynamic_sql.html) –

+0

Ponticelli @OMG - il parametro sniffing potrebbe essere un problema con sp_ExecuteSQL? – JNK

+0

@JNK: Da quando ho riscontrato il comportamento, ho comunque inserito lo snodo anti-param in base all'impostazione predefinita. –

risposta

8

No.

È possibile visualizzare sia i piani di esecuzione e confrontarli con la seguente query.

SELECT usecounts, cacheobjtype, objtype, text, query_plan, value as set_options 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
CROSS APPLY sys.dm_exec_query_plan(plan_handle) 
cross APPLY sys.dm_exec_plan_attributes(plan_handle) AS epa 
where text like '%Some unique string in your query%' 
              and attribute='set_options' 

La versione sp_executesql avrà un objtype di "preparato"

+3

Perché i piani di esecuzione dovrebbero essere così radicalmente diversi? Ad esempio, ho esaminato il mio piano di esecuzione delle query direttamente da Sql Management Studio (richiede 3 secondi) e il piano di esecuzione da sp_executeSql (richiede più di 5 minuti). il piano dallo sp_executeSql ignora completamente alcuni degli indici chiave trovati dalla chiamata diretta. Qualcuno può spiegare perché una chiamata da studio di gestione trova le chiavi, ma la chiamata tramite sp_ExecuteSql non lo fa? –

+0

@NathanTregillus - Probabilmente con lo snifing dei parametri, è possibile consultare l'XML del piano memorizzato nella cache per visualizzare i valori dei parametri con cui il piano è stato effettivamente compilato. –

+0

grazie per la risposta @MartinSmith. In realtà è dovuto al modo in cui usiamo contextInfo come filtro nella nostra vista e come non viene incluso nel piano di esecuzione –

1

Sperimentato lo stesso comportamento. (imposta le opzioni uguali) Query normale che produce piano parallelo e usando sp_executesql ha prodotto un piano seriale.

declare @xyzParam1 datetime,@xyzParam2 datetime 
select @xyzParam1='Sep 1 2014 12:00:00:000AM',@xyzParam2='Sep 26 2014 11:59:59:000PM' 
SELECT * FROM Theview WHERE departuretime BETWEEN @xyzParam1 AND @xyzParam2 
; 

vs

exec sp_executesql N'SELECT * FROM Theview WHERE departuretime BETWEEN @xyzParam1 AND @xyzParam2',N'@xyzParam1 datetime,@xyzParam2 datetime',@xyzParam1='Sep 1 2014 12:00:00:000AM',@xyzParam2='Sep 26 2014 11:59:59:000PM' 

sono riuscito ad ottenere un risultato ottimale modificando la vista utilizzata perché conteneva esempio left join per i dati che erano sempre previsti. (Convertito in inner join)

Ora la query regolare raccoglie lo stesso piano di quella ottenuta utilizzando sp_executesql e le prestazioni è il modo migliore.

Problemi correlati