Mentre rispetto il mittente, umilmente non sono d'accordo con la risposta fornita e non per "motivi religiosi". In altre parole, credo che Microsoft non abbia fornito alcuna possibilità che riduca la necessità di una guida per l'uso delle procedure memorizzate.
Qualsiasi guida fornita a uno sviluppatore che favorisce l'uso di query SQL con testo non elaborato deve essere riempita con molti avvertimenti, in modo tale che penso che il consiglio più prudente sia quello di incoraggiare notevolmente l'uso delle Stored procedure e di scoraggiare i team di sviluppatori dall'impegnarsi nella pratica dell'incorporamento di istruzioni SQL nel codice o l'invio di richieste SQL basate su testo non elaborate e semplici, al di fuori degli SPROC SQL (procedure memorizzate).
Penso che la semplice risposta alla domanda sul perché usare uno SPROC sia come supponeva il mittente: gli SPROC vengono analizzati, ottimizzati e compilati. Pertanto, i loro piani di query / esecuzione vengono memorizzati nella cache perché hai salvato una rappresentazione statica di una query e, di solito, la varierai solo in base a parametri, il che non è vero nel caso di istruzioni SQL copiate / incollate che probabilmente si trasformano da pagina a pagina e componente / livello e sono spesso variati nella misura in cui è possibile specificare da chiamata a chiamata tabelle diverse, anche nomi di database. Consentire questo tipo di dinamica ad hocL'invio di SQL riduce notevolmente la probabilità che DB Engine riutilizzi il piano di query per le istruzioni ad hoc, secondo alcune regole molto rigide. Qui sto facendo la distinzione tra query dinamiche ad hoc (nello spirito della domanda sollevata) rispetto all'uso dell'efficiente System SPROC sp_executesql.
Più specificamente, ci sono i seguenti componenti:
- Piani di query seriali e paralleli che non contengono il contesto dell'utente e consentono il riutilizzo da parte del motore DB.
- Contesto di esecuzione che consente il riutilizzo di un piano di query da parte di un nuovo utente con parametri di dati diversi.
- Cache di procedura che è ciò che il motore DB richiede per creare l'efficienza che cerchiamo.
Quando un'istruzione SQL viene emessa da una pagina Web, definita "istruzione ad hoc", il motore cerca un piano di esecuzione esistente per gestire la richiesta. Poiché si tratta di un testo inviato da un utente, verrà importato, analizzato, compilato ed eseguito, se valido. Al momento riceverà un costo di query pari a zero. Il costo della query viene utilizzato quando il motore DB utilizza il suo algoritmo per determinare quali piani di esecuzione eliminare dalla cache.
Le query ad hoc ricevono un valore di costo della query originale pari a zero, per impostazione predefinita. Alla successiva esecuzione dello stesso identico testo di query ad hoc, mediante un altro processo utente (o lo stesso), il costo della query corrente viene reimpostato sul costo di compilazione originale. Poiché il nostro costo di compilazione di query ad hoc è zero, ciò non è di buon auspicio per la possibilità di riutilizzo. Ovviamente, zero è il numero intero meno valutato, ma perché dovrebbe essere sfrattato?
Quando sorgono pressioni di memoria, e lo faranno se si dispone di un sito di uso frequente, il motore DB utilizza un algoritmo di cleanup per determinare come può recuperare la memoria utilizzata dalla cache delle procedure. Utilizza il costo della query corrente per decidere quali piani eliminare. Come puoi immaginare, i piani con un costo pari a zero sono i primi ad essere sfrattati dalla cache perché zero significa essenzialmente "nessun utente corrente o riferimenti a questo piano".
- Nota: piani di esecuzione ad hoc: il costo corrente viene aumentato da ogni processo utente, dal costo di compilazione originale del piano. Tuttavia, il costo massimo di un piano non può essere superiore al costo di compilazione originale ... nel caso di query ad hoc ... zero. Quindi, sarà "aumentato" di quel valore ... zero - il che significa essenzialmente che rimarrà il piano di costo più basso.
Pertanto, è molto probabile che un tale piano venga sfrattato per primo quando sorgono pressioni di memoria.
Pertanto, se si dispone di un server con molta memoria "oltre le proprie esigenze", è possibile che non si verifichi questo problema con la stessa frequenza di un server occupato che ha solo memoria "sufficiente" per gestire il proprio carico di lavoro. (Siamo spiacenti, la capacità e l'utilizzo della memoria del server sono in qualche modo soggettivi / relativi, sebbene l'algoritmo non lo sia.)
Ora, se in realtà non sono corretto su uno o più punti, sono certamente aperto alla correzione.
Infine, l'autore ha scritto:
"Ora abbiamo un'ottimizzazione a livello di istruzione, quindi una query correttamente parametrizzata proveniente da un'applicazione può sfruttare lo stesso piano di esecuzione di quella query incorporata in una procedura memorizzata."
Credo che l'autore si riferisca all'opzione "ottimizza per carichi di lavoro ad hoc".
In tal caso, questa opzione consente un processo in due passaggi che evita di inviare immediatamente l'intero piano di query alla cache delle procedure. Invia solo uno stub di query più piccolo lì. Se una chiamata di query esatta viene rinviata al server mentre lo stub di query è ancora nella cache delle procedure, il piano di esecuzione dell'intera query viene salvato nella cache delle procedure, in quel momento. Ciò consente di risparmiare memoria, che durante gli incidenti di pressione della memoria, può consentire all'algoritmo di sfratto di sfrattare lo stub meno frequentemente di un piano di query più grande che è stato memorizzato nella cache. Ancora una volta, questo dipende dalla memoria e dall'utilizzo del server.
Tuttavia, devi attivare questa opzione, poiché è disattivata per impostazione predefinita.
Infine, voglio sottolineare che, spesso, il motivo per cui gli sviluppatori incorporano SQL in pagine, componenti e altri luoghi è perché desiderano essere flessibili e inviare query SQL dinamiche al motore di database. Pertanto, in un caso d'uso reale, l'invio dello stesso testo, call-over-call, è improbabile che si verifichino così come lo sono la cache / l'efficienza che cerchiamo, quando si inviano query ad hoc a SQL Server.
Per ulteriori informazioni, consultare:
https://technet.microsoft.com/en-us/library/ms181055(v=sql.105).aspx
http://sqlmag.com/database-performance-tuning/don-t-fear-dynamic-sql
Meglio,
Henry