Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Dynamisch erstelltes SQL vs. Parameter in SQL Server

Ich überspringe das SQL-Injection-Argument, das einfach zu bekannt ist, und konzentriere mich nur auf den SQL-Aspekt von Parametern im Vergleich zu Nicht-Parametern.

Wenn Sie einen SQL-Batch an den Server senden, muss jeder Batch analysiert werden, um verstanden zu werden. Wie jeder andere Compiler muss der SQL-Compiler einen AST erzeugen aus dem Text und bearbeiten dann den Syntaxbaum. Letztendlich wandelt der Optimierer den Syntaxbaum in einen Ausführungsbaum um und erstellt schließlich einen Ausführungsplan, der tatsächlich ausgeführt wird. In den dunklen Zeiten um 1995 machte es einen Unterschied, ob der Stapel eine Ad-Hoc-Abfrage oder eine gespeicherte Prozedur war, aber heute macht es absolut nichts mehr, sie sind alle gleich.

Nun, wo Parameter einen Unterschied machen, ist, dass ein Client eine Abfrage wie select * from table where primary_key = @pk sendet sendet genau denselben SQL-Text jedes Mal, egal welcher Wert interessiert. Was dann passiert, ist, dass das gesamte Der oben beschriebene Prozess I ist kurzgeschlossen. SQL durchsucht im Arbeitsspeicher einen Ausführungsplan nach dem unverarbeiteten, nicht geparsten Text Es hat (basierend auf einem Hash-Digest der Eingabe) diesen Plan empfangen und, falls gefunden, ausgeführt. Das heißt, kein Parsing, keine Optimierung, nichts, der Batch geht direkt in die Ausführung . Auf OLTP-Systemen, die jede Sekunde Hunderte und Tausende kleiner Anfragen ausführen, macht dieser schnelle Pfad einen enormen Leistungsunterschied.

Wenn Sie die Abfrage in der Form select * from table where primary_key = 1 senden dann muss SQL ihn zumindest parsen, um zu verstehen, was sich im Text befindet, da der Text wahrscheinlich neu ist und sich von allen vorherigen Stapeln unterscheidet, die er gesehen hat (sogar ein einzelnes Zeichen wie 1 vs. 2 macht die gesamte Charge anders). Es arbeitet dann mit dem resultierenden Syntaxbaum und versucht einen Prozess namens Simple Parametrierung . Wenn die Abfrage automatisch parametrisiert werden kann, findet SQL wahrscheinlich einen zwischengespeicherten Ausführungsplan dafür aus anderen Abfragen, die zuvor mit anderen pk-Werten ausgeführt wurden, und verwendet diesen Plan wieder, sodass Ihre Abfrage zumindest nicht optimiert werden muss und Sie dies überspringen Schritt der Erstellung eines tatsächlichen Ausführungsplans. Aber auf keinen Fall haben Sie den vollständigen Kurzschluss erreicht, den kürzestmöglichen Weg, den Sie mit einer echten Client-parametrisierten Abfrage erreichen.

Sie können sich das SQL Server, SQL Statistics Object ansehen Leistungszähler Ihres Servers. Der Zähler Auto-Param Attempts/sec wird mehrmals pro Sekunde angezeigt, dass SQL eine ohne Parameter empfangene Abfrage in eine automatisch parametrisierte übersetzen muss. Jeder Versuch kann vermieden werden, wenn Sie die Abfrage im Client richtig parametrieren. Wenn Sie auch eine hohe Anzahl von Failed Auto-Params/sec haben Noch schlimmer ist, dass die Abfragen den vollständigen Zyklus der Optimierung und Ausführungsplanerstellung durchlaufen.