OPTION FORCE ORDER verbessert die Leistung, bis Zeilen gelöscht werden

9

Ich habe eine etwas komplexe SQL Server 2008-Abfrage (ungefähr 200 Zeilen ziemlich dichtes SQL), die nicht so ausgeführt wurde, wie ich es brauchte. Im Laufe der Zeit sank die Leistung von etwa 0,5 Sekunden auf etwa 2 Sekunden.

Beim Blick auf den Ausführungsplan war es ziemlich offensichtlich, dass durch die Neuordnung der Verknüpfungen die Leistung verbessert werden konnte. Ich tat es und es tat es ... bis zu ungefähr 0,3 Sekunden. Jetzt hat die Abfrage den Hinweis "OPTION FORCE ORDER" und das Leben ist gut.

Heute komme ich und räume die Datenbank auf. Ich archiviere ungefähr 20% der Zeilen und ergreife keine Aktion in der relevanten Datenbank, außer das Löschen von Zeilen ... der Ausführungsplan wird VOLLSTÄNDIG abgespritzt . Es wird völlig falsch eingeschätzt, wie viele Zeilen bestimmte Teilbäume zurückgeben, und (zum Beispiel) ersetzt a:

<Hash>

mit

<NestedLoops Optimized='false' WithUnorderedPrefetch='true'>

Jetzt steigt die Abfragezeit von ungefähr 0,3 s auf ungefähr 18 s. (!) Nur weil ich Zeilen gelöscht habe. Wenn ich den Abfragehinweis entferne, habe ich wieder eine Abfragezeit von ca. 2 Sekunden. Besser, aber schlechter.

Ich habe das Problem nach dem Wiederherstellen der Datenbank an mehreren Standorten und Servern reproduziert. Das einfache Löschen von etwa 20% der Zeilen aus jeder Tabelle verursacht immer dieses Problem.

  1. Ist dies normal für eine erzwungene Verknüpfungsreihenfolge, um die Abfrageschätzungen vollständig ungenau zu machen (und damit die Abfragezeiten unvorhersehbar zu machen)?
  2. Sollte ich nur damit rechnen, dass ich entweder eine nicht optimale Abfrageleistung akzeptieren oder sie wie ein Falke beobachten und Abfragehinweise häufig manuell bearbeiten muss? Oder vielleicht auch jeden Join andeuten? .3s bis 2s ist ein großer Erfolg.
  3. Ist es offensichtlich, warum der Optimierer nach dem Löschen von Zeilen explodierte? Beispiel: "Ja, es wurde ein Beispielscan durchgeführt. Da ich die meisten Zeilen früher im Datenverlauf archiviert habe, hat das Beispiel nur spärliche Ergebnisse geliefert, sodass die Notwendigkeit einer sortierten Hash-Operation unterschätzt wurde."

Wenn Sie Ausführungspläne sehen möchten, schlagen Sie bitte einen Ort vor, an dem ich sie veröffentlichen kann. Ansonsten habe ich das atemberaubendste Stück probiert. Hier ist die grundlegende Fehleinschätzung: Zahlen in Parens sind (geschätzte: tatsächliche) Zeilen.

                             /  Clustered Index Scan (908:7229)
Nested Loops (Inner Join) --<
                             \  NonClustered Index Seek (1:7229)

Beachten Sie, dass die innere Schleife voraussichtlich 908 Zeilen scannt, stattdessen jedoch 52.258.441. Wenn es genau gewesen wäre, hätte dieser Zweig ungefähr 2 ms statt 12 Sekunden gelaufen. Vor dem Löschen der Zeilen war diese Schätzung der inneren Verknüpfung nur um den Gesamtfaktor 2 verschoben und wurde als Hash-Übereinstimmung für zwei gruppierte Indizes durchgeführt.

Shannon
quelle

Antworten:

6

Ist dies normal für eine erzwungene Verknüpfungsreihenfolge, um die Abfrageschätzungen vollständig ungenau zu machen (und damit die Abfragezeiten unvorhersehbar zu machen)?

Die Verwendung von FORCE ORDER macht Schätzungen nicht ungenau, das Löschen von Zeilen jedoch. Das Erzwingen einer Aktualisierung der Statistiken in der Tabelle kann die Schätzgenauigkeit verbessern.

Sollte ich nur damit rechnen, dass ich entweder eine nicht optimale Abfrageleistung akzeptieren oder sie wie ein Falke beobachten und Abfragehinweise häufig manuell bearbeiten muss? Oder vielleicht auch jeden Join andeuten? .3s bis 2s ist ein großer Erfolg.

Es wäre vorzuziehen, sicherzustellen, dass der Optimierer die Informationen erhält, die er zur Erstellung des besten Plans benötigt, ohne den Hinweis FORCE ORDER zu verwenden. Auf diese Weise sollten Änderungen an der zugrunde liegenden Datenverteilung besser bewältigt werden können, ohne dass manuelle Eingriffe erforderlich sind. Wenn die Art der Daten jedoch so ist, dass die Kardinalität von Stunde zu Stunde oder von Tag zu Stunde erheblich variieren kann, sollten Sie einen Planleitfaden verwenden, um sicherzustellen, dass der Plan festgelegt ist.

Ist es offensichtlich, warum der Optimierer nach dem Löschen von Zeilen explodierte? Beispiel: "Ja, es wurde ein Beispielscan durchgeführt. Da ich die meisten Zeilen früher im Datenverlauf archiviert habe, hat das Beispiel nur spärliche Ergebnisse geliefert, sodass die Notwendigkeit einer sortierten Hash-Operation unterschätzt wurde."

Sie haben die Anzahl der Zeilen in den Problemtabellen nicht erwähnt, aber es ist wahrscheinlich, dass die Löschungen auch:

  • Es wurden nicht genügend Zeilen entfernt, um eine Statistikaktualisierung auszulösen. Dies sollte auftreten, wenn 20% der Zeilen geändert wurden. Es besteht jedoch die Möglichkeit, das Ablaufverfolgungsflag 2371 zu verwenden, um einen dynamischen Schwellenwert zu aktivieren.
  • hat eine Statistikaktualisierung ausgelöst, aber die gesammelte Stichprobe war nicht repräsentativ. Korrigieren Sie dies, indem Sie ein manuelles Update WITH FULLSCAN ausführen .

Es kann auch vorkommen, dass Sie auf altmodische Parameter-Sniffing- Probleme stoßen , für die es unzählige Möglichkeiten gibt, diese zu umgehen. WITH RECOMPILE ist möglicherweise eine teure Option, um sie bei einer so großen Abfrage anzugeben, aber es lohnt sich, sie sowohl auf Prozedur- als auch auf Anweisungsebene zu untersuchen.

Mark Storey-Smith
quelle
Nur eine Klarstellung, es ist wahrscheinlich Semantik: "Die Verwendung von FORCE ORDER macht Schätzungen nicht ungenau, das Löschen von Zeilen hat es getan." Sie denken also, es ist nur eine zufällige Chance, dass das Entfernen der "FORCE ORDER" die Abfrage so stark verbessert hat? Der Hinweis hat den Optimierer nicht dazu gebracht, sich auf Statistiken zu verlassen, auf die er lieber weniger Wert legt, oder wurde im Anwendungstest nicht entdeckt, weil diese weniger zuverlässige Statistik selten entscheidend war?
Shannon
Ich denke ja, da die von den Optimierern bevorzugte Planauswahl zufällig mit den ungenauen Statistiken zurechtkommt, der Plan, der sich aus der erzwungenen Verknüpfungsreihenfolge ergibt, jedoch nicht. Mir ist nicht bekannt, dass FORCE ORDER Änderungen an der Statistikauswertung bewirkt. Jemand anderes mischt sich ein, wenn er etwas Gegenteiliges weiß. Sie müssen auch prüfen, ob der Wert, den Sie für OPTIMIEREN FÜR ausgewählt haben, angemessen ist. Könnte sein, dass Statistiken absolut in Ordnung sind, aber Sie erzwingen einen Plan basierend auf einem Wert, der nicht repräsentativ ist.
Mark Storey-Smith
Richtig. Ich habe das gleiche Leistungsproblem beim Übergeben der Parameter genau so, wie ich sie optimiert habe. Danke noch einmal.
Shannon