Ich habe eine lange laufende Abfrage (Faktentabelle mit 100 Millionen Zeilen, die eine Reihe kleiner Dim-Tabellen verbinden und dann gruppieren), die auf Tempdb verschüttet wird, obwohl der CE (nach einigen Optimierungen) sehr nahe an der tatsächlichen Anzahl der Zeilen liegt, siehe Plan ::
Auf der Suche nach einer Erklärung bemerkte ich die folgenden Informationen zur Speicherzuweisung:
Umgebung: SQL Server 2012 SP1 Enterprise, Server-RAM 256 GB, maximaler SQL Server-Speicher 200 GB, Pufferpoolgröße 42 GB, maximaler Arbeitsbereich 156 GB (GrantedMemory = 156 * 25% ~ = 38 GB)
Fragen
- Bedeutet das, egal wie gut das CE ist, die Abfrage hat keine Chance, nicht überzulaufen? da die Abfrage max RAM ist fest auf 38 GB begrenzt
- Berücksichtigt das Abfrageoptimierungsprogramm beim Erstellen des Plans nicht den maximalen Abfrage-RAM? (Das Erzwingen eines Hash-Match-Aggregats würde den Sortierschritt eliminieren und die Abfrageleistung erheblich verbessern. Leider stammt die eigentliche Abfrage von Cognos und wir haben keine Kontrolle darüber.)
- Wird es hier sinnvoll sein, die Obergrenze von 25% auf nahezu 100% zu erhöhen? (unter der Annahme, dass der Serverzugriff gesteuert werden kann, um die Anzahl gleichzeitiger Abfrageanforderungen zu begrenzen)
Anonymisierter Abfrageplan beim Einfügen des Plans
Wenn Sie ein Hash-Match-Aggregat erzwingen (anstelle eines Sort + Stream-Aggregats), wird die Abfrage konsistent drei- bis viermal schneller beendet. Leider stammt die eigentliche Abfrage von Cognos, und wir können sie nicht ändern.
Der Hash-Aggregatplan enthält keine Hash-Verschüttung. Das Abfrageoptimierungsprogramm wählt kein Hash-Übereinstimmungsaggregat aus, da die CPU-Kosten der Hash-Gruppe zwei- bis dreimal höher sind als bei der Stream-Aggregation, wenn ich die Operatorkosten für Hash-gegen-Stream-Aggregat betrachte.
Sowohl im Stream- als auch im Hash-Aggregat entsprechen die geschätzten Ausgabezeilen genau der Eingabe (~ 100 Millionen Zeilen).
Die Abfrage verwendet einen einzelnen NC-Spaltenspeicherindex, und alle Spaltenstatistiken werden regelmäßig aktualisiert.
quelle
Antworten:
Die Gesamtspeichergewährung für Ihre Abfrage ist angesichts Ihrer aktuellen Hardware- und SQL Server-Konfiguration auf 37 GB begrenzt.
Wenn die Sortierung nicht innerhalb des Speicheranteils (0.860743 in diesem Plan) der Abfragespeichergewährung durchgeführt werden kann, wird sie auf tempdb übertragen . Beachten Sie auch, dass diese parallele Sortierung ihren Anteil an der Zuweisung des Abfragespeichers gleichmäßig auf 12 Threads verteilt und diese Zuordnung zur Laufzeit nicht neu ausgeglichen werden kann.
Ja, aber nur als Input für den allgemeinen Kostenrahmen. Der Optimierer wählt den Plan aus, der je nach Modell am günstigsten aussieht. Wenn die Zahlen falsch sind, ist die Planauswahl wahrscheinlich nicht optimal.
In Ihrem Fall ist die tatsächliche Anzahl der vom Stream-Aggregat erzeugten Zeilen erheblich geringer als geschätzt:
Das Optimierungsprogramm bevorzugt Hash-Aggregat, wenn weniger, größere Gruppen erwartet werden (da jede Gruppe einen Platz in der Hash-Tabelle belegt). Die Fehlinformationen über die Dichte führen zu einer falschen Auswahl von Sortieren + Stream-Aggregat.
Der beste Plan wäre wahrscheinlich ein Hash-Join anstelle des Joins mit verschachtelten Schleifen und ein Hash-Aggregat. Dies sollte in der Lage sein, die Stapelverarbeitung auf den wichtigen Aggregationsschritt auszudehnen.
SQL Server 2012 war in seinen Übergängen zwischen Zeilen- und Stapelmodus recht eingeschränkt. Die Ausführungs-Engine kehrt nach Beginn der Verarbeitung im Zeilenmodus nie mehr in den Stapelmodus zurück (Zeile-Stapel-Zeile ist also in Ordnung, Stapel-Zeile-Stapel jedoch nicht).
Wenn Sie den für diese Abfrage verfügbaren Speicherplatz erhöhen möchten, können Sie dies sicherlich tun, indem Sie Ihr Resource Governor-Setup ändern. Erhöhen Sie den Grenzwert um Grad, um festzustellen, ob Sie einen guten Kompromiss finden können. Ich wäre vorsichtig, wenn ich zu 100% zu nahe kommen würde.
Wenn die Abfrage für eine Plananleitung geeignet ist, versuchen Sie es mit einem
HASH GROUP
Hinweis.Längerfristig zahlt sich ein Upgrade auf SQL Server 2016 aus, da mehr Operatoren im Batch-Modus (einschließlich Sortieren) ausgeführt werden können, dynamische Speicherzuwächse möglich sind und ... etwa tausend weitere Verbesserungen bei der Verarbeitung des Spaltenspeichers / Batch-Modus im Allgemeinen.
quelle
Ich kann Ihre Fragen teilweise beantworten.
1) Ich bin mir nicht sicher, ob ich Ihre Frage genau verstehe. Es ist nicht wahr, dass SQL Server nur auf Tempdb übertragen wird, weil eine Kardinalitätsschätzung falsch ist. Manchmal erwartet SQL Server, dass ein ausreichend guter Plan auf tempdb übertragen wird.
2) Das Abfrageoptimierungsprogramm berücksichtigt beim Erstellen des Plans den Speicher auf dem Server. Eine nützliche Übung kann darin bestehen, die für Ihre Abfrage verfügbare Speichermenge zu ändern, um zu sehen, wie sich der Abfrageplan ändert. Sie können dies tun, indem Sie die Speichereinstellungen auf dem Server mithilfe des Ressourcen-Governors oder des undokumentierten Befehls DBCC OPTIMIZER WHAT_IF () ändern . WHAT_IF ist nützlich, wenn Sie sehen möchten, wie der Abfrageplan mit mehr Speicher als 200 GB aussieht.
Wie Sie bereits betont haben, verwendet das Abfrageoptimierungsprogramm kein Hash-Match-Aggregat, da es davon ausgeht, dass die CPU-Kosten dieses Operators viel höher sind als die Sortierung. Eines der Kriterien, die ein Hash-Match-Aggregat für das Optimierungsprogramm attraktiv machen, ist, wenn SQL Server schätzt, dass nicht viele unterschiedliche Zeilen zurückgegeben werden. Für Ihre Abfrage ist SQL Server der Ansicht, dass mit GROUP BY keine Zeilen entfernt werden.
Wie hoch sind die geschätzten Kosten für die Pläne und wie ändern sie sich, wenn Sie den für die Abfrage verfügbaren Speicher ändern?
3) Ich weiß es nicht, aber es ist definitiv etwas, das Sie sorgfältig testen sollten. Sicherere Optionen wären die Erhöhung des maximalen SQL Server-RAM (200 scheint etwas niedrig zu sein, aber möglicherweise sind andere Anwendungen auf dem Server installiert oder dies liegt außerhalb Ihrer Kontrolle) oder die Verbesserung der Tempdb-Leistung. Ich kann mir ein paar andere Ideen zur Leistungsverbesserung vorstellen, aber alle sind Longshots.
Versuchen Sie, eine einfachere Abfrage auszuführen, die nur ein GROUP BY für die Faktentabelle ausführt. Gibt es eine Möglichkeit, die Anzahl der unterschiedlichen Werte besser abzuschätzen? Könnte das Erstellen mehrspaltiger Statistiken helfen?
Wenn Sie die Abfrage nicht ändern können, können Sie versuchen, die Tabelle, auf die verwiesen wird, durch eine Ansicht zu ersetzen, die die benötigten Daten auswählt, jedoch den Plan ändert. Dies kann in einigen Fällen hilfreich sein, aber ich kann mir keine Möglichkeit vorstellen, die Technik hier anzuwenden.
Es hört sich so an, als hätten Sie einiges an Kontrolle über diesen Server, sodass Sie versuchen könnten , einen Planleitfaden zu erstellen . Ich habe das noch nie gemacht und noch nie jemanden etwas Positives über Planführer sagen hören.
quelle