2013-03-15 7 views
6

Ich habe eine dynamische Teil von SQL. Es dauert ungefähr 4 Minuten zu laufen. Wenn ich stattdessen die Ausgabe der SQL-Anweisung nehme und diese stattdessen ausführe, dauert es etwa 20 Sekunden. Warum die Diskrepanz? Ich weiß, dass es einige Zeit dauern würde, das SQL in der dynamischen Version aufzubauen, aber ich kann mir nicht vorstellen, dass es so teuer ist.Dynamisches SQL dauert viel viel länger als das hartkodierte Äquivalent

Wer hat irgendwelche Ideen? Die zwei Abfragen sollten identisch sein, also vermutete ich, dass es etwas seltsames beim Caching von Abfrageplänen war, aber ich habe nicht wirklich eine Idee.

Bearbeiten: Um zu verdeutlichen, was ich meine, indem Sie die Ausgabe.

In der dynamischen SQL die letzte Zeile ist

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

ich den Wert von myQuery nahm und steckte es in seine eigene SQL-Datei. Das dauert 20 Sekunden, während das dynamische Ausführen 4 Minuten dauert.

Bearbeiten 2 Ich entfernte die Parameter. Ich habe interessante Ergebnisse bekommen. Die dynamische SQL-Anweisung hat eine Leistungsverbesserung erfahren. Die hardcoded Version sah einen enormen Leistungseinbruch. Die beiden sind jetzt ungefähr gleich.

+9

Bitte geben Sie Ihren Code ein. – Taryn

+0

Können Sie Ihren Code anzeigen? –

+0

Sie sollten viel mehr Informationen hinzufügen, aber wenn hardcoded so viel schneller ist, dann machen Sie definitiv etwas falsch. – TFennis

Antwort

6

Ich gehe davon aus, dass Sie Microsoft SQL Server verwenden (Sie haben nur Ihre Frage "sql" getaggt).

In einigen Fällen können unterschiedliche Parameterwerte zu einem anderen Optimierungsplan führen. Dann wird dieser Optimierungsplan zwischengespeichert und beim nächsten Ausführen der Abfrage mit anderen Parameterwerten verwendet. Aber der Optimierungsplan ist nicht der beste Plan für die nachfolgenden Parameterwerte.

Hier ist ein Artikel über dieses Problem und einige Abhilfen: https://www.simple-talk.com/sql/t-sql-programming/parameter-sniffing/

Also ja - es gibt einige Fälle, in denen eine parametrisierte Abfrage mit einer schlechten Leistung im Vergleich zu laufen die gleiche Abfrage ohne Parametrierung führen kann.

Wir können nicht wissen, ob dies in Ihrem Fall gilt, wenn es Ihnen nicht möglich ist, Ihren Code zu posten.

Ich respektiere, dass Sie das nicht tun können - durch die Veröffentlichung in StackOverflow, you implicitly license your code and/or words with a Creative Commons license. Es wäre jedoch nicht angemessen, den Code Ihres Arbeitgebers zu teilen, es sei denn, er stimmt dem zu.

+0

OP hat das gegenteilige Problem; Abfrage ohne Parametrierung läuft wesentlich langsamer als Abfrage mit Parametrierung. –

+0

@PieterGeerkens, so lese ich das beschriebene Problem nicht. –

+0

In beiden Fällen kann die Parametrisierung nicht zu unterschiedlichen Abfrageplänen führen. Und unterschiedliche Abfragepläne führen zu unterschiedlichen Laufzeiten. –

4

Wenn Sie SQL Server 2008 oder höher verwenden, die OPTIMIZE FOR UNKNOWN Abfrage-Hinweis verwenden. Fügen Sie die folgenden bis zum Ende Ihrer dynamischen Abfrage:

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

Experiment mit wechselnden in oder aus den drei Eingängen @ var1, @ var2 und @ var3. Ja, es kann wirklich so teuer sein, wenn der Abfrageoptimierer versucht, Statistiken für etwas zu verwenden, das wirklich ad hoc ist.Wenn eine oder mehrere Ihrer Variablen ziemlich vorhersehbar sind, optimieren Sie diese für bestimmte Werte und optimieren Sie die verbleibenden für unbekannt. Schauen Sie sich diesen Link für mehr Details an.

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

klar zu sein, ist dies wahrscheinlich ein Parameter Sniffing Problem wie oben durch ninjaPixel angegeben. OPTIMIZE FOR UNKNOWN kann Ihnen bessere Ergebnisse liefern, als jede Abfrage neu zu kompilieren, da der Abfrageoptimierer zur Kompilierung Statistiken verwendet.

+0

Danke. Ich wollte ninjapixel zuerst das Kopfgeld geben, aber diese Antwort ist noch besser. –

+0

Ich bin froh, dass ich helfen konnte – quest4truth

2

Fügen Sie Ihrer dynamischen Abfrage einen Kommentar hinzu. in dem Kommentar Werten von Variablen Put @ var1, @ var2, @ var3 und etc.

Es wird wie folgt aussehen:

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

So wird Ausführungsplan nur für verschiedene Werte neu kompilieren.

Verwandte Themen