Wie können Sie alle alten Abfragepläne in Microsoft SQL Server löschen?

12

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?

Michael Riley - AKA Gunny
quelle

Antworten:

7

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.

Garik
quelle
Ich bin damit einverstanden WITH RECOMPILE zu verwenden. Ich habe dies mit Systemen gemacht, die ich erstellt habe. Ich habe jedoch keinen Zugriff auf die SQL-Quelle ... sie wird aus einer Anwendung heraus ausgeführt.
Michael Riley - AKA Gunny
@Cape Cod Gunny in diesem Fall versuchen Sie es mit DBCC FLUSHPROCINDB: Wird verwendet, um den Cache für gespeicherte Prozeduren für eine bestimmte Datenbank auf einem SQL Server zu löschen, nicht für den gesamten SQL Server. Sie können diesen Befehl vor dem Testen verwenden, um sicherzustellen, dass frühere Pläne für gespeicherte Prozeduren die Testergebnisse nicht beeinträchtigen. Beispiel: DECLARE @intDBID INTEGER SET @intDBID = (SELECT DBID FROM master.dbo.sysdatabases WHERE Name = 'Datenbankname') DBCC FLUSHPROCINDB (@intDBID)
Garik
Das Problem wurde gelöst. Es stellte sich heraus, dass in einer temporären Tabelle, in der Suchkriterien gespeichert wurden, ständig Daten gesammelt wurden. Der Prozess soll die Daten aus dieser Tabelle abschneiden, bevor die Daten erfasst werden. Danke für das nette SQL-Snippet.
Michael Riley - AKA Gunny
13

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.

SQLRockstar
quelle
Der DBCC FREEPROCCACHE hat das Problem nicht behoben. Ich überwache die Tätigkeit und die Ereignisse. Es gibt 0 physische E / A. Es scheint an dieser Anwendung zu hängen: .Net Sql Client Data Provider. Der Wartetyp ist CXPACKET.
Michael Riley - AKA Gunny
CXPACKET impliziert, dass Ihre Abfrage parallel ausgeführt wird. Können Sie feststellen, wie viele Threads für die Abfrage ausgeführt werden, und deren Wartezeiten überprüfen? Möglicherweise möchten Sie Adam Machanics kostenloses Tool WhoIsActive sqlblog.com/files/folders/release/entry29675.aspx verwenden .
SQLRockstar
7

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

Matt M
quelle
Ich habe versucht, DBCC FREEPROCCACHE zu verwenden, und das Problem konnte nicht behoben werden. Ich beendete den Prozess nach 1 Stunde.
Michael Riley - AKA Gunny