Beim Lesen verschiedener Erklärungen zum Zwischenspeichern von Ausführungsplänen durch Microsoft SQL Server bin ich verwirrt über die Vorteile der Verwendung gespeicherter Prozeduren anstelle nicht dynamischer Abfragen.
Mit einer nicht dynamischen Abfrage meine ich eine vollständig parametrisierte Abfragezeichenfolge, die sich nicht durch mehrere Aufrufe ändert.
So wie ich es verstehe:
Der Ausführungsplan wird sowohl für eine gespeicherte Prozedur als auch für eine normale Abfrage zwischengespeichert.
Für eine gespeicherte Prozedur wird der Ausführungsplan vorberechnet, was beim ersten Aufruf der gespeicherten Prozedur zu einem geringfügigen Vorteil gegenüber normalen Abfragen führt.
Die Quellen sehen für mich eher widersprüchlich aus:
Der Artikel zum Zwischenspeichern und Wiederverwenden von Ausführungsplänen in MSDN unterscheidet nicht zwischen parametrisierten Abfragen und gespeicherten Prozeduren. In den Unterabschnitten wird die Bedeutung parametrisierter Abfragen hervorgehoben, damit SQL Server den Ausführungsplan problemlos zwischenspeichern kann.
Ausführungspläne für SQL Server-Abfragen - Basics behauptet das Gegenteil (Schwerpunkt Mine):
Bei der Ausführung von Ad-hoc-Abfragen werden Abfragepläne auf der Grundlage des vollständigen Codes erstellt, sodass unterschiedliche Parameter oder Codeänderungen die Wiederverwendung des vorhandenen Plans verhindern .
In DBA.StackExchange gibt der Kommentar zu einer Antwort zu den Vorteilen gespeicherter Prozeduren an, dass parametrisierte Abfragen genau den gleichen Effekt haben wie gespeicherte Prozeduren.
In dem Kontext, in dem der Ausführungsplan nicht aus dem Cache geworfen wird und in dem ich aus Versuchsgründen milliardenfach eine ziemlich komplizierte Abfrage ausführen möchte, die von einem Ausführungsplan profitieren würde und einen Parameter verwendet, der sich ändert Gibt es jedes Mal einen Vorteil in Bezug auf das Caching von Ausführungsplänen¹, wenn gespeicherte Prozeduren anstelle einer normalen parametrisierten Abfrage verwendet werden?
¹ Außerhalb des Geltungsbereichs des Ausführungsplans ergeben sich geringfügige Leistungsvorteile bei der Verwendung einer gespeicherten Prozedur, z. B. in Bezug auf den Netzwerk-Footprint: Die Übergabe des Namens der gespeicherten Prozedur und ihrer Parameter ist geringfügig besser als die Übergabe der gesamten Abfrage. Diese Vorteile liegen außerhalb des Rahmens meiner Frage, bei der es ausschließlich um den Cache für Ausführungspläne geht.
quelle
Antworten:
Die Antwort ist auch als eigenständiger Blog-Artikel verfügbar .
Um es herauszufinden, habe ich einige Tests durchgeführt. Ziel ist es, dieselbe parametrisierte Abfrage entweder direkt von C # oder durch Aufrufen einer gespeicherten Prozedur auszuführen und die Laufzeitleistung zu vergleichen.
Ich habe begonnen, eine gespeicherte Prozedur zu erstellen, die eine Beispielabfrage mithilfe der Adventure Works-Datenbank ausführt:
Dann verwende ich den folgenden Code, um die Leistungen zu vergleichen:
Hinweis
option (recompile)
undwith recompile
. Dadurch wird SQL Server gezwungen, zuvor zwischengespeicherte Ausführungspläne zu verwerfen.Jede Abfrage wird jedes Mal hundertmal mit einem anderen Parameter ausgeführt. Die vom Server verbrachte Zeit wird auf der Clientseite gemessen.
Durch Ausführen
DBCC FreeProcCache; DBCC DropCleanbuffers;
vor dem Sammeln von Metriken stelle ich sicher, dass alle zuvor zwischengespeicherten Ausführungspläne entfernt werden.Das Ausführen dieses Codes ergibt die folgende Ausgabe:
Lassen Sie es uns noch einmal ausführen:
Es scheint, dass die Leistung zwischen gespeicherten Prozeduren und direkten Abfragen sehr eng ist. Wenn ich den Code ein Dutzend Mal ausführe, stelle ich fest, dass gespeicherte Prozeduren etwas schnell zu sein scheinen, aber die Lücke ist sehr eng. Durch die Weitergabe der gesamten Abfrage entstehen möglicherweise zusätzliche Kosten, die sich erhöhen können, wenn SQL Server auf einem dedizierten Computer mit einem langsamen LAN zwischen ihm und dem Anwendungsserver gehostet wird.
Lassen Sie uns nun das Caching des Ausführungsplans aktivieren und sehen, was passiert. Dazu entferne ich
option (recompile)
undwith recompile
aus dem Code. Hier ist die neue Ausgabe:Es wird deutlich, dass das Caching sowohl für direkte Abfragen als auch für gespeicherte Prozeduren genau den gleichen Effekt hat. In beiden Fällen wird die Zeit auf nahezu null Millisekunden reduziert, und die teuerste Abfrage ist die erste, die nach dem Entfernen zwischengespeicherter Ausführungspläne ausgeführt wird.
Wenn Sie denselben Code erneut ausführen, wird ein ähnliches Muster angezeigt. Manchmal sind Abfragen schneller und manchmal sind gespeicherte Prozeduren schneller. Aber jedes Mal ist die erste Abfrage die teuerste, und alle anderen sind nahe null Millisekunden.
SQL-Verbindung erneut öffnen
Wenn die SQL-Verbindung für jede Abfrage geöffnet wird, z. B. in diesem leicht geänderten Code:
Die beobachteten Metriken sind sehr ähnlich:
mit
option (recompile)
undwith recompile
und:ohne.
Unter der Haube
Mal sehen, was unter der Haube passiert. Die folgende Abfrage zeigt zwischengespeicherte Ausführungspläne:
Wenn Sie diese Abfrage nach hundertmaliger Ausführung der gespeicherten Prozeduren ausführen, sieht das Ergebnis der Abfrage folgendermaßen aus:
Wenn die Abfrage hundertmal direkt ausgeführt wird, lautet das Ergebnis:
Fazit
Der Ausführungsplan wird für gespeicherte Prozeduren und direkte Abfragen zwischengespeichert.
Die Leistung zwischen gespeicherten Prozeduren und direkten Abfragen ist sehr ähnlich, wenn der SQL Server und die Anwendung auf demselben Computer gehostet werden. Wenn SQL Server auf einem dedizierten Server gehostet wird, auf den über LAN zugegriffen wird, kann die Verwendung gespeicherter Prozeduren zu einer besseren Leistung führen.
quelle
Beim Plan-Caching handelt es sich bei einer gespeicherten Prozedur um eine parametrisierte Abfrage. Sie verwenden dieselben Abfragepläne. Es gibt möglicherweise einen geringen Aufwand bei der Verwendung übereinander, nur weil sie sich in der Ausführungsphase unterscheiden, aber ich habe nie einen signifikanten Unterschied bemerkt.
Die Vorteile gespeicherter Prozeduren hängen mit Sicherheit, Wartbarkeit und Bereitstellung zusammen. Abgesehen von dem inhärenten Schutz parametrisierter Abfragen gegenüber dynamischem SQL der alten Schule.
quelle