L'uso di IF in T-SQL indebolisce o interrompe la memorizzazione nella cache del piano di esecuzione?


20

Mi è stato suggerito che l'uso delle istruzioni IF nei batch t-SQL è dannoso per le prestazioni. Sto cercando di trovare qualche conferma o convalidare questa affermazione. Sto usando SQL Server 2005 e 2008.

L'affermazione è che con il seguente batch: -

IF @parameter = 0
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END

SQL Server non può riutilizzare il piano di esecuzione generato perché l'esecuzione successiva potrebbe richiedere un ramo diverso. Ciò implica che SQL Server eliminerà completamente un ramo dal piano di esecuzione sulla base del fatto che per l'esecuzione corrente può già determinare quale ramo è necessario. È davvero vero?

Inoltre cosa succede in questo caso: -

IF EXISTS (SELECT ....)
 BEGIN
  SELECT ... something
 END

ELSE
 BEGIN
  SELECT ... something else
 END

dove non è possibile determinare in anticipo quale ramo verrà eseguito?



1
SQL Server può riutilizzare il piano di esecuzione e non considera i rami, ma solo le istruzioni contenute nei rami.
MartinC,

Risposte:


10

SQL Server ottimizza il processo di compilazione del piano di query per la procedura memorizzata ignorando i rami condizionali all'interno della procedura memorizzata. Il piano verrà generato in base ai parametri utilizzati per la prima esecuzione, ciò causerà problemi se i parametri sono diversi per i rami.

Vorrei inserire l'SQL per ciascuno dei rami nella propria procedura memorizzata, in modo che il piano generato si basi sull'utilizzo effettivo dei parametri per quel ramo.


6

L'unica scorciatoia sarà IF 1 = 1

Sia @parameter che EXISTS richiedono ancora l'elaborazione per il "caso generale" ( @parameter = 42diciamo)

Dicendo che ... cosa dice il piano di esecuzione attuale e il profiler che cattura gli eventi di ricomposizione? (Non mi piacciono i piani stimati secondo la risposta di Jao)


3

Prova a visualizzare il piano di esecuzione stimato, non l'attuale. Vedrai che il primo contiene un CONDoperatore.

Questo operatore è stato incluso anche nel piano di esecuzione memorizzato nella cache. Nel tuo esempio il piano di escissione stimato conterrà un operatore COND e 2 rami SELECT e sarà quindi completamente riutilizzabile. Perché quando si esegue un batch SQL Server valuta non solo le istruzioni DML ma anche tutte le altre, ottenendole dal piano.

Il piano di esecuzione interno è una struttura simile all'albero delle espressioni.


0

I piani verranno creati in base ai parametri passati, quindi in realtà direi di no: avere una logica condizionale che normalmente si basa su parametri non è dannoso per le prestazioni.

Verranno prodotti più piani, supponendo che i parametri causino una varianza sufficiente da consentire a Query Optimizer.

Puoi vedere quale attivando il piano di esecuzione Show, eseguendo gli script, noterai le differenze nel piano. Quando esegui le procedure (suppongo che le procedure siano memorizzate qui), noterai che la prima volta è generalmente più veloce, il secondo hit utilizza il piano memorizzato. Modifica i parametri e ripeti, quindi esegui i parametri originali - in teoria il piano sarà ancora nella cache ma dipende dall'uso del server (segni di spunta della cache - non rimangono per sempre ..) ecc.


0

Forse è stato migliorato nel 2005 e nel 2008, ma l'uso dei condizionali nel 2000 sarebbe molto probabilmente peggio di quanto tu descriva, compilerebbe un piano per gestire al meglio la prima esecuzione della procedura e quindi userà quel piano per eseguire la procedura anche quando le condizioni cambiato. Nella mia esperienza, ciò ha causato l'esecuzione di query eseguite in pochi minuti. Anche se uso il 2008 adesso e ho usato il 2005, non posso commentare come funzionano i coditionals poiché non li uso più.


2
2005+ ha una ricompilazione a livello di dichiarazione, quindi non hai più "un piano per sp" per tutto il tempo
gbn
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.