Wir haben eine Standardanwendung, die eine Microsoft SQL-Datenbank verwendet. Innerhalb dieser Anwendung wählen wir verschiedene Auswahlkriterien für jeden Bericht aus. Diese Anwendung führt dann diese Berichte aus.
Ich glaube, wir haben ein Problem mit dem Abfrageplan. Der erste Bericht, den wir jeden Tag erstellen, dauert 7 Minuten. Jeder Bericht, den wir nach dem ersten Bericht erstellen, dauert mehr als eine Stunde.
Jede Nacht führen wir einen geplanten Task aus, der den SQL Server-Agenten und den SQL Server anhält und startet. In dieser einen Instanz von SQL Server befinden sich ungefähr 25 weitere Datenbanken. Bei keiner anderen Datenbank treten Leistungsprobleme auf, nur bei der von mir bereits erwähnten Standard-Datenbank.
Gibt es eine Möglichkeit, alle Abfragepläne zu löschen, über die SQL Server derzeit im Speicher verfügt?
Wie kann ich dies tun, ohne 30 Benutzer zu beeinträchtigen, die auf andere Datenbanken auf demselben Server angewiesen sind?
quelle
Antworten:
Ich entschuldige mich für meine vorherige Antwort.
1) Fügen Sie der Anweisung CREATE PROCEDURE die Option WITH RECOMPILE hinzu, wenn Sie wissen, dass Ihre Abfrage bei jeder Ausführung von der gespeicherten Prozedur abweicht. Die WITH RECOMPILE-Option verhindert die Wiederverwendung des Ausführungsplans für gespeicherte Prozeduren, sodass SQL Server keinen Plan für diese Prozedur zwischenspeichert und die Prozedur zur Laufzeit neu kompiliert wird. Die Verwendung der WITH RECOMPILE-Option kann die Leistung steigern, wenn Ihre Abfrage bei jeder Ausführung von der gespeicherten Prozedur abweicht, da in diesem Fall der falsche Ausführungsplan nicht verwendet wird.
2) Sie müssen einen Planleitfaden erstellen, der einen USE PLAN- Abfragehinweis für jeden Abfragetyp (jeden Anforderungstyp für gespeicherte Prozeduren) verwendet, um den Ausführungsplan zu erzwingen.
Hier ist ein Artikel über den Ausführungsplan, der helfen kann.
quelle
Sie haben hier zwei Fragen gestellt. Zunächst möchten Sie wissen, ob Sie alle im Arbeitsspeicher gespeicherten Pläne für eine SQL-Instanz entfernen können. Dies geschieht mit DBCC FREEPROCCACHE, wie Matt M vorgeschlagen hat.
Die zweite Frage, die Sie gestellt haben, lautet: "Wie kann ich dies tun, ohne 30 Benutzer zu beeinträchtigen, die auf andere Datenbanken auf demselben Server angewiesen sind?". Die kurze Antwort lautet "Sie können nicht". Wenn Sie alle Pläne entfernen, werden die anderen Benutzer, die sich darauf verlassen, dass sich Pläne im Speicher befinden, wahrscheinlich einen Leistungseinbruch erleiden.
Die Problemumgehung hierfür erfordert einige manuelle Eingriffe. Sie können DBCC FREEPROCCACHE verwenden, um bestimmte Pläne zu entfernen, sofern Sie über das plan_handle verfügen.
Nach dem, was Sie oben beschrieben haben, klingt es nach einem Planproblem, aber ich bin nicht sicher, ob das Entfernen von Plänen die Antwort ist. Ich würde Sie in die Richtung des Parameter-Schnüffelns weisen, bevor Sie über das Entfernen von Plänen nachdenken:
http://blogs.msdn.com/b/conor_cunningham_msft/archive/2010/08/11/conor-vs-misbehaving-parameterized-queries-optimize-for-hints.aspx
Sie sollten in der Lage sein, die Abfragen zu optimieren, anstatt planmäßig mit DBCC FREEPROCCACHE herumzuspielen. Ich rate Ihnen auch, die Warteereignisse für Ihre Instanz zu analysieren.
quelle
DBCC FREEPROCCACHE
Mit diesem Befehl können Sie den gesamten Prozedurcache auf einen einzigen Befehl reduzieren. Lesen Sie unbedingt die Dokumentation, bevor Sie diesen Befehl verwenden. Lesen Sie mehrmals den Abschnitt "Bemerkungen".
Durch das Löschen des Prozedurcaches werden gespeicherte Prozedurcaches bei der nächsten Verwendung neu kompiliert. Dies könnte die Leistung beeinträchtigen. Vorsichtig verwenden!
Matt
quelle