2009-06-17 13 views
9

Ho una stored procedure che accetta un ingresso di data che viene successivamente impostato sulla data corrente se nessun valore viene passato:SQL piano di poveri stored procedure di esecuzione delle prestazioni - parametro sniffing

CREATE PROCEDURE MyProc 
    @MyDate DATETIME = NULL 
AS 
    IF @MyDate IS NULL SET @MyDate = CURRENT_TIMESTAMP 
    -- Do Something using @MyDate 

Ho problemi per cui se @MyDate viene passato come NULL quando la stored procedure viene prima generata, la prestazione è sempre terribile per tutti i valori di ingresso (NULL o altro), wheras se/viene passato quando la stored procedure viene compilato prestazioni è una data la data corrente bene per tutti i valori di input (NULL o altro).

Ciò che è anche confusione è che il piano di esecuzione poveri che si genera in è terribile anche quando il valore di @MyDate utilizzato è in realtà NULL (e non impostato su CURRENT_TIMESTAMP dalla dichiarazione IF)

I' ve scoperto che disattivando il parametro sniffing (dal spoofing parametro) consente di risolvere il mio problema:

CREATE PROCEDURE MyProc 
    @MyDate DATETIME = NULL 
AS 
    DECLARE @MyDate_Copy DATETIME 
    SET @MyDate_Copy = @MyDate 
    IF @MyDate_Copy IS NULL SET @MyDate_Copy = CURRENT_TIMESTAMP 
    -- Do Something using @MyDate_Copy 

so che questo è qualcosa a che fare con il parametro sniffing, ma tutti gli esempi che ho visto di "sniffing dei parametri Gone Bad" hanno coinvolto la stored procedure essere passato compilato con un parametro non rappresentativo passato, tuttavia qui sto vedendo che il piano di esecuzione è terribile per tutti i valori concepibili che il server SQL potrebbe pensare che il parametro potrebbe prendere nel punto in cui viene eseguita l'istruzione - NULL, CURRENT_TIMESTAMP o in altro modo .

Qualcuno ha qualche idea sul perché questo sta accadendo?

+1

Questo è interessante, ma sei in realtà non fare una domanda da nessuna parte qui ... – cjk

+0

Appena notato che :-) – Justin

risposta

6

Fondamentalmente sì - sniffing dei parametri (in alcuni livelli di patch di) SQL Server 2005 è male rotto. Ho visto piani che effettivamente non completano mai (in poche ore su un piccolo set di dati) anche per insiemi di dati piccoli (poche migliaia di righe) che si completano in secondi dopo la mascheratura dei parametri. E questo è nei casi in cui il parametro è sempre stato lo stesso numero. Aggiungo che allo stesso tempo avevo a che fare con questo, ho riscontrato molti problemi con LEFT JOIN/NULL non completati e li ho sostituiti con NOT IN o NOT EXISTS e questo ha risolto il piano verso qualcosa che avrebbe completato. Di nuovo, un (molto scarso) problema del piano di esecuzione. All'epoca in cui avevo a che fare con questo, gli amministratori di database non mi davano accesso SHOWPLAN e da quando ho iniziato a mascherare ogni parametro SP, non ho avuto ulteriori problemi relativi al piano di esecuzione in cui avrei dovuto scavare per non completarlo .

In SQL Server 2008 è possibile utilizzare OPTIMIZE FOR UNKNOWN.

0

Un modo sono stato in grado di aggirare questo problema in (SQL Server 2005) invece di mascherare i parametri da redeclaring parametri locali è stato quello di aggiungere delle query hint di ottimizzazione.

Ecco un buon post sul blog che parla più su di esso: Parameter Sniffing in SqlServer 2005

ho usato: OPZIONE (massima (@p = '-1'))

Problemi correlati