Obwohl ich den Einsender respektiere, bin ich mit der gegebenen Antwort demütig nicht einverstanden und nicht aus "religiösen Gründen". Mit anderen Worten, ich glaube, es gibt keine Möglichkeit, die Microsoft zur Verfügung gestellt hat, die den Bedarf an Anleitungen zur Verwendung gespeicherter Prozeduren verringert.
Jede Anleitung, die einem Entwickler zur Verfügung gestellt wird, der die Verwendung von SQL-Abfragen mit Rohtext bevorzugt, muss mit zahlreichen Einschränkungen versehen sein. Ich halte es daher für den klügsten Rat, die Verwendung gespeicherter Prozeduren zu fördern und Ihre Entwicklerteams davon abzuhalten, sich an der Praxis zu beteiligen Einbetten von SQL-Anweisungen in Code oder Senden von unformatierten, textbasierten SQL-Anforderungen außerhalb von SQL-SPROCs (gespeicherten Prozeduren).
Ich denke, die einfache Antwort auf die Frage, warum ein SPROC verwendet wird, lautet, wie der Absender vermutet: SPROCs werden analysiert, optimiert und kompiliert. Daher werden ihre Abfrage- / Ausführungspläne zwischengespeichert, da Sie eine statische Darstellung einer Abfrage gespeichert haben und diese normalerweise nur um Parameter variieren. Dies gilt nicht für kopierte / eingefügte SQL-Anweisungen, die sich wahrscheinlich ändern von Seite zu Seite und von Komponente / Schicht und sind oft so variabel, dass von Aufruf zu Aufruf verschiedene Tabellen, sogar Datenbanknamen, angegeben werden können. Unter Berücksichtigung dieser Art von dynamischem Ad-hocDurch die SQL-Übermittlung wird die Wahrscheinlichkeit, dass das DB-Modul den Abfrageplan für Ihre Ad-hoc-Anweisungen nach sehr strengen Regeln wiederverwendet, erheblich verringert. Hier unterscheide ich zwischen dynamischen Ad-hoc-Abfragen (im Sinne der aufgeworfenen Frage) und der Verwendung des effizienten Systems SPROC sp_executesql.
Insbesondere gibt es die folgenden Komponenten:
- Serielle und parallele Abfragepläne, die den Benutzerkontext nicht enthalten und die Wiederverwendung durch die DB-Engine ermöglichen.
- Ausführungskontext, der die Wiederverwendung eines Abfrageplans durch einen neuen Benutzer mit unterschiedlichen Datenparametern ermöglicht.
- Prozedur-Cache, den die DB-Engine abfragt, um die angestrebten Effizienzen zu erzielen.
Wenn eine SQL-Anweisung von einer Webseite ausgegeben wird, die als "Ad-hoc-Anweisung" bezeichnet wird, sucht das Modul nach einem vorhandenen Ausführungsplan, um die Anforderung zu verarbeiten. Da es sich um von einem Benutzer gesendeten Text handelt, wird dieser aufgenommen, analysiert, kompiliert und ausgeführt, sofern er gültig ist. Zu diesem Zeitpunkt wird es eine Abfrage von Null erhalten. Abfragekosten werden verwendet, wenn das DB-Modul seinen Algorithmus verwendet, um zu bestimmen, welche Ausführungspläne aus dem Cache entfernt werden sollen.
Ad-hoc-Abfragen erhalten standardmäßig einen ursprünglichen Abfragekostenwert von Null. Bei der anschließenden Ausführung des exakt gleichen Ad-hoc-Abfragetexts durch einen anderen Benutzerprozess (oder denselben) werden die aktuellen Abfragekosten auf die ursprünglichen Kompilierungskosten zurückgesetzt. Da die Kosten für die Kompilierung von Ad-hoc-Abfragen gleich Null sind, ist die Möglichkeit der Wiederverwendung nicht gut. Natürlich ist Null die am wenigsten wertvolle Ganzzahl, aber warum sollte sie entfernt werden?
Wenn Speicherprobleme auftreten und wenn Sie eine häufig verwendete Site haben, verwendet das DB-Modul einen Bereinigungsalgorithmus, um zu ermitteln, wie es den vom Prozedurcache verwendeten Speicher wiederherstellen kann. Es verwendet die aktuellen Abfragekosten, um zu entscheiden, welche Pläne entfernt werden sollen. Wie Sie sich vorstellen können, werden Pläne mit einem Preis von Null als erstes aus dem Cache entfernt, da Null im Wesentlichen "keine aktuellen Benutzer dieses Plans oder Verweise auf diesen Plan" bedeutet.
- Hinweis: Ad-hoc-Ausführungspläne - Die aktuellen Kosten werden von jedem Benutzerprozess um die ursprünglichen Kompilierungskosten des Plans erhöht. Die maximalen Kosten eines Plans dürfen jedoch nicht höher sein als die ursprünglichen Kompilierungskosten ... bei Ad-hoc-Abfragen ... Null. Es wird also um diesen Wert "erhöht" ... Null - was im Wesentlichen bedeutet, dass es der Plan mit den niedrigsten Kosten bleibt.
Daher ist es sehr wahrscheinlich, dass ein solcher Plan zuerst geräumt wird, wenn Speicherdruck entsteht.
Wenn Sie also einen Server mit viel Arbeitsspeicher haben, der "über Ihre Anforderungen hinaus" geht, tritt dieses Problem möglicherweise nicht so häufig auf wie bei einem ausgelasteten Server, der nur "genügend" Arbeitsspeicher hat, um seine Arbeitslast zu bewältigen. (Die Speicherkapazität und Auslastung des Servers ist leider etwas subjektiv / relativ, der Algorithmus jedoch nicht.)
Wenn ich in Bezug auf einen oder mehrere Punkte sachlich falsch liege, bin ich auf jeden Fall bereit, korrigiert zu werden.
Zuletzt schrieb der Autor:
"Jetzt haben wir eine Optimierung auf Anweisungsebene, sodass eine ordnungsgemäß parametrisierte Abfrage, die von einer Anwendung stammt, denselben Ausführungsplan wie die in eine gespeicherte Prozedur eingebettete Abfrage verwenden kann."
Ich glaube, der Autor bezieht sich auf die Option "Für Ad-hoc-Workloads optimieren".
In diesem Fall ist mit dieser Option ein zweistufiger Prozess möglich, bei dem nicht sofort der vollständige Abfrageplan an den Prozedurcache gesendet wird. Es wird dort nur ein kleinerer Abfragestub gesendet. Wenn ein genauer Abfrageaufruf zurück an den Server gesendet wird, während sich der Abfragestub noch im Prozedurcache befindet, wird zu diesem Zeitpunkt der vollständige Abfrageausführungsplan im Prozedurcache gespeichert. Dies spart Speicher, der es dem Auslagerungsalgorithmus bei Speicherdruckereignissen möglicherweise ermöglicht, den Stub seltener auszuräumen als bei einem größeren Abfrageplan, der zwischengespeichert wurde. Dies hängt wiederum vom Arbeitsspeicher und der Auslastung Ihres Servers ab.
Sie müssen diese Option jedoch aktivieren, da sie standardmäßig deaktiviert ist.
Abschließend möchte ich betonen, dass Entwickler SQL häufig nur deshalb in Seiten, Komponenten und andere Bereiche einbetten, weil sie flexibel sein und dynamische SQL-Abfragen an das Datenbankmodul senden möchten. In einem realen Anwendungsfall ist es daher unwahrscheinlich, dass derselbe Text, Call-over-Call, übermittelt wird, wie auch die von uns angestrebten Zwischenspeicherungs- / Effizienzvorteile, wenn Ad-hoc-Abfragen an SQL Server gesendet werden.
Weitere Informationen finden Sie unter:
https://technet.microsoft.com/en-us/library/ms181055(v=sql.105).aspx
http://sqlmag.com/database-performance-tuning/don-t-fear-dynamic-sql
Am besten
Henry