Ich habe eine Abfrage mit mehreren Ausführungsplänen. Der einem Plan zugewiesene Speicher ist im Vergleich zum zweiten sehr groß
basierend auf diesem Artikel https://blogs.msdn.microsoft.com/sql_server_team/addressing-large-memory-grant-requests-from-optimized-nested-loops/
Das Problem tritt auf, wenn die äußere Tabelle des Nested-Loop-Joins ein Prädikat enthält, das das Ergebnis nach einer kleinen Eingabe filtert, die Stapelsortierung jedoch anscheinend eine Schätzung der Kardinalität verwendet, die der gesamten äußeren Tabelle entspricht. Dies kann zu einer vermeintlich übermäßigen Speicherzuweisung führen, die auf einem sehr gleichzeitigen Server verschiedene Nebenwirkungen haben kann, z. B. OOM-Bedingungen, Speicherdruck für die Räumung des Plan-Cache oder unerwartete Wartezeiten bei RESOURCE_SEMAPHORE. Wir haben gesehen, wie eine einzelne Abfrage, die diesem Muster entspricht, tatsächlich mehrere GB gewährten Speicher auf High-End-Computern (1 TB + RAM) erhalten kann.
Eine Möglichkeit bestand bisher darin, diese Funktion mithilfe des Ablaufverfolgungsflags 2340 global zu deaktivieren, wie in KB 2801413 beschrieben. In SQL Server 2016 RC0 haben wir das Verhalten jedoch geändert, um den Vorteil der Optimierung beizubehalten. Jetzt basiert das maximale Gewährungslimit auf dem verfügbaren Speicher Speicherplatz gewähren. Diese Verbesserung führt auch zu einer besseren Skalierbarkeit, da mehr Abfragen mit einem geringeren Speicherbedarf ausgeführt werden können. Wir versuchen, dieses Verhalten wieder auf ein bevorstehendes zu portieren. Wir haben dieses Verhalten auf SQL Server 2014 Service Pack 2 portiert und bieten wie üblich einen Mehrwert für In-Market-Versionen.
Dies ist genau das, was ich sehe, jedoch verwende ich SQL Server 2016 Enterprise.
Dies sind die Ausführungspläne
https://www.brentozar.com/pastetheplan/?id=SJ0mYAy0b
https://www.brentozar.com/pastetheplan/?id=BJzutC1R-
Meine Fragen sind
Was ist der Grund für 2 Ausführungspläne?
Das Optimierungsprogramm verwendet den Top-Ausführungsplan. Ich habe ihn gezwungen, den unteren Plan zu verwenden, aber nach einiger Zeit geht es wieder zum Top-Plan. Gibt es einen Grund dafür?
Wie kann ich dieses Problem beheben? Dieses Problem führt zum Absturz der Anwendung (es gab viele
RESOURCE_SEMAPHORE
Wartezeiten und die Anwendung reagiert nicht mehr). Soll ich den Hinweis verwenden:DISABLE_OPTIMIZED_NESTED_LOOP
oderTrace Flag 2340
?HINWEIS: Ich habe das XML überprüft und beide Pläne haben
NestedLoops Optimized="false"