Sto avendo problemi con prestazioni lente in un'istruzione select SQL con alcuni parametri, per la stessa query, eseguendo questa selezione usando sp_executesql
modo ci vuole doppio tempo che il modo inline.
Il problema è che nel server sql sp_execute-waynon sta usando il piano di esecuzione ottimale. Sebbene i piani siano diversi, sembra che in entrambi i casi gli indici delle tabelle vengano utilizzati correttamente. Non capisco davvero perché le prestazioni siano così diverse.
La mia query originale è più complessa ma da provarecapire cosa sta succedendo, ho semplificato la query originale a una selezione con 3 tabelle e 2 join. La differenza principale è l'uso di Hash Match in modo ottimale, non so davvero il significato di questo, ma è l'unica differenza posso vedere.
Piano ottimale (corrispondenza hash, oltre 3 secondi)
Piano sbagliato (nessuna corrispondenza hash, stessi indici di quelli precedenti, oltre 12 secondi)
Penso che il mio problema non sia il "parametro sniffing", nel mio caso la query è sempre lenta per tutti i valori dei parametri distinti perché il piano di esecuzione è sempre errato.
OPTION (RECOMPILE)
non aiuta,sp_executesql
continua ad andare lentamente e in linea richiede più tempo (perché la query compila sempre il piano di esecuzione)Le statistiche per le tabelle sono aggiornate
Devo usare
sp_executesql
modo perché sembra che i servizi di segnalazione incapsulino il select insp_executesql
chiamate
Qualcuno sa perché sp_executesql
genera un piano di esecuzione diverso (errato) rispetto alla query in linea?
MODIFICARE: Le query non utilizzavano gli stessi indici, suppongo che poiché l'albero di esecuzione non è lo stesso e sqlserver prende gli indici come preferisce, in allegato puoi trovare nuovi piani di esecuzione per forzare l'uso degli stessi indici, le prestazioni ora sono anche peggiori, da 12 secondi a più di 15 minuti (ho cancellato) in query lenta. Non sono davvero interessato a eseguire questa specifica query più velocemente, come dico che questa non è la vera query che sto trattando, quello che sto cercando di capire è il motivo per cui i piani di esecuzione sono così diversi tra inline-query e sp_executesql
-query.
C'è qualche opzione magica in sp_executesql
questo funziona correttamente? :)
Ottimale
Lento
risposte:
2 per risposta № 1La mia comprensione è che sp_executesql mantiene un piano memorizzato nella cache dopo la prima esecuzione. Le query successive potrebbero utilizzare un piano memorizzato nella cache. È possibile utilizzare il seguente comando per cancellare il INTERO Cache delle procedure SQL Server.
DBCC FREEPROCCACHE
http://msdn.microsoft.com/en-us/library/ms174283.aspx