2013-03-15 14 views
6

Ho un pezzo dinamico di SQL. Ci vogliono circa 4 minuti per correre. Se invece prendo l'output dell'SQL e lo eseguo, occorrono circa 20 secondi. Perché la discrepanza? So che ci vorrebbe un po 'di tempo per costruire l'SQL nella versione dinamica, ma non riesco a immaginare che sia così costoso.SQL dinamico che impiega molto più tempo dell'equivalente codificato

Qualcuno ha qualche idea? Le due query dovrebbero essere identiche, quindi sospettavo che fosse qualcosa di strano con il caching del piano di query, ma in realtà non ho molte idee.

Modifica: Per chiarire cosa intendo prendendo l'output.

In SQL dinamico l'ultima riga è

EXEC sp_executesql @myQuery, 
    N'@var1 INT, 
    @var2 INT, 
    @var2 INT', 
    @var1, 
    @var2, 
    @var3 

ho preso il valore di myQuery e metterlo in un file SQL. Questo è in esecuzione a 20 secondi mentre quello dinamico che usa execute richiede 4 minuti.

Modifica 2 Ho rimosso i parametri. Ho ottenuto risultati interessanti. L'istruzione SQL dinamica ha visto un miglioramento delle prestazioni. La versione hardcoded ha visto un enorme successo nelle prestazioni. I due sono circa uguali ora.

+9

Inserisci il tuo codice. – Taryn

+0

Puoi mostrare il tuo codice? –

+0

Dovresti aggiungere molte più informazioni, ma se hardcoded è molto più veloce allora stai sicuramente facendo qualcosa di sbagliato. – TFennis

risposta

6

Suppongo che tu stia utilizzando Microsoft SQL Server (hai codificato solo la tua domanda "sql").

Ci sono alcuni casi in cui valori di parametri diversi possono comportare un piano di ottimizzazione diverso. Quindi il piano di ottimizzazione viene memorizzato nella cache e utilizzato la volta successiva in cui si esegue la query con valori di parametro diversi. Ma il piano di ottimizzazione non è il miglior piano per i successivi valori dei parametri.

Ecco un articolo su questo problema e alcune soluzioni: https://www.simple-talk.com/sql/t-sql-programming/parameter-sniffing/

Quindi sì - ci sono alcuni casi in cui utilizzando una query con parametri in grado di compromettere le prestazioni rispetto alla corsa stessa query senza parametrizzazione.

Non possiamo sapere se questo si applica nel tuo caso se non sei libero di inserire il tuo codice.

Rispetto che non è possibile farlo pubblicando su StackOverflow, you implicitly license your code and/or words with a Creative Commons license. Ma non sarebbe appropriato condividere il codice che appartiene al tuo datore di lavoro, a meno che non sia d'accordo.

+0

OP sta avendo il problema oppiaceo; query senza parametrizzazione eseguita molto più lentamente della query con parametrizzazione. –

+0

@PieterGeerkens, non è così che leggo il problema descritto dall'OP. –

+0

In entrambi i casi, la parametrizzazione rispetto a non può causare piani di query diversi. E piani di query diversi causeranno tempi di esecuzione diversi. –

4

Se stai usando SQL Server 2008 o versioni successive, utilizzare l'OPTIMIZE FOR UNKNOWN hint di query. Aggiungere quanto segue alla fine della vostra query dinamica:

OPTION (OPTIMIZE FOR (@var1 UNKNOWN, @var2 UNKNOWN, @var3 UNKNOWN)) 

Esperimento con il cambiamento dentro o fuori i tre ingressi @ var1, @ @ VAR 2 ed var3. Sì, può essere davvero costoso se il Query Optimizer tenta di utilizzare le statistiche su qualcosa che è veramente ad hoc.Se una o più delle tue variabili sono abbastanza prevedibili, ottimizza quelle per valori specifici e ottimizza il rimanente per sconosciuto. Dai un'occhiata a questo link per maggiori dettagli.

https://blogs.msdn.microsoft.com/sqlprogrammability/2008/11/26/optimize-for-unknown-a-little-known-sql-server-2008-feature/

Per essere chiari, questo è probabilmente un parametro di sniffing problema come indicato dalla ninjaPixel sopra. OPTIMIZE FOR UNKNOWN può fornire risultati migliori rispetto alla ricompilazione di ogni query perché lo strumento di ottimizzazione delle query si basa sulle statistiche per eseguire la sua compilazione.

+0

Grazie. Avevo intenzione di dare la taglia a ninjaPixel inizialmente, ma questa risposta è ancora migliore. –

+0

Contento di aver potuto aiutare – quest4truth

2

Aggiungi un commento alla tua query dinamica. metto nei valori di commento delle variabili @ var1, var2 @, @ var3 ed ecc

che sarà del tipo:

EXEC sp_executesql @myQuery, 
    /* var1Value, var2Value, var3Value */  
    N'@var1 INT, 
    @var2 INT, 
    @var2 INT', 
    @var1, 
    @var2, 
    @var3 

Così, piano di esecuzione sarà ricompilare solo per valori diversi.

Problemi correlati