Ich habe eine sehr große Abfrage (~ 630 Zeilen), die viele verschachtelte SELECT
Anweisungen enthält und aus mehreren Ansichten abgerufen wird. Auf unserem SQL Server ist die Parallelität auf 2 mit einem Schwellenwert von 95 festgelegt (auf diese Weise festgelegt, weil unser DBA sie basierend auf einigen anderen Anwendungen optimiert hat). Diese Abfrage dauert seit kurzem 5-10 Minuten, normalerweise weniger als eine Minute. Bei der Untersuchung der Ursache haben wir festgestellt, dass sie niemals Parallelität auslöst, immer seriell ausgeführt wird und den Verdacht hat, dass dies etwas mit ihrer Leistung zu tun hat. Was seltsam ist, ist, dass wir beim Experimentieren den Schwellenwert sogar wieder auf den Standardwert von 5 Sekunden gesenkt haben und er immer noch nicht parallel läuft. Was könnte es verhindern?
Wir haben die Tests in einer Nicht-Produktionsumgebung durchgeführt, die zu diesem Zeitpunkt von niemand anderem verwendet wurde. Dies war also die einzige Abfrage, die ausgeführt wurde. Unser DBA versuchte auch Dinge wie das Löschen von Caches und Plänen und sogar das Recycling des Systems, aber es hatte keine Auswirkungen.
Update 1 : Gemäß Kommentaren habe ich überprüft, dass die Statistiken jede Nacht aktualisiert werden, aber das Problem besteht weiterhin. Wir führen den Code tatsächlich auf eine frühere Version zurück, die keine so schwerwiegenden Leistungsprobleme aufwies, werden diesen Code jedoch weiterhin testen, da er die Leistung gegenüber dem alten Code verbessern sollte und dies tatsächlich beim ersten Testen getan hat. Wird hier entsprechend aktualisiert.
quelle
Antworten:
Es gibt viele Gründe, warum der Optimierer keinen parallelen Plan erstellt (oder nicht erstellen kann). Breit:
MAX_DOP = 1
wird oder nur ein logischer Prozessor für SQL Server verfügbar istParallelitätshemmende Operationen
Es gibt viele Operationen, die Parallelität verhindern, entweder weil sie in einem Parallelplan keinen Sinn ergeben oder weil das Produkt sie (noch) nicht unterstützt. Einige Beispiele (nicht erschöpfend!) Für Dinge, die den gesamten Plan zwingen, seriell zu sein:
OBJECT_NAME
,ENCYPTBYCERT
undIDENT_CURRENT
Jeder Verweis auf eine Tabelle (oder Ansicht) mit einer berechneten Spalte, die eine nicht inline T-SQL-Skalarfunktion verwendet, führt zu einem seriellen Plan, auch wenn auf diese Spalte in der Abfrage nicht verwiesen wird .
Fehler bei der Kardinalitätsschätzung
Wenn nichts die Parallelität in der Zielabfrage absolut verhindert, wählt der Optimierer möglicherweise immer noch eine serielle Alternative, wenn die geschätzten Kosten niedriger sind . Dies kann durch eine falsche Kardinalitätsschätzung verursacht werden.
Kostenmodellbeschränkungen
SQL Server verwendet ein Modell, um die Laufzeitkosten jedes Operators in einem Abfrageplan zu schätzen. Dieses Modell kann einen seriellen Plan falsch kosten, der billiger ist als die parallele Alternative. Der Optimierer wählt immer die billigste Option, die er in Betracht zieht.
Wenn SQL Server einen parallelen Plan kostet, werden die CPU-Kosten für einen parallelen Iterator im Allgemeinen um einen Faktor reduziert, der dem erwarteten Laufzeit-DOP entspricht. Pläne mit Nested-Loops-Joins können ein besonderes Problem sein, da auf der Innenseite fast immer mehrere Threads seriell ausgeführt werden. Die Parallelitätssymbole sind weiterhin vorhanden, zeigen jedoch an, dass DOP-unabhängige serielle Threads vorhanden sind.
Die Unterscheidung ist vielleicht subtil, aber sie erklärt (a), warum Operatoren, die normalerweise eine serielle Zone erzwingen, auf der Innenseite einer Schleifenverbindung "parallel" laufen können; und (b) der Optimierer reduziert die CPU-Kosten auf der Innenseite nicht um den geschätzten Laufzeit-DOP. Dies benachteiligt verschachtelte Schleifen bei der Parallelitätskostenberechnung im Vergleich zu Hash- und Merge-Joins und kann erklären, warum der Optimierer möglicherweise keinen Plan für parallele verschachtelte Schleifen auswählt.
Probleme mit dem Codepfad des Optimierers
Der Optimierer kommt möglicherweise überhaupt nicht so weit, einen parallelen Plan auszuwerten. Dies kann unter anderem dadurch geschehen, dass der endgültige Plan in der Phase des Trivialplans gefunden wird. Wenn ein Trivialplan möglich ist und die resultierenden Kosten unter dem konfigurierten Kostenschwellenwert für Parallelität liegen, werden die vollständigen Optimierungsphasen übersprungen und ein serieller Plan wird sofort zurückgegeben.
Abfragen, die den Trivial Plan bestehen, können die Optimierung möglicherweise vorzeitig beenden (bevor die Parallelität berücksichtigt wird), entweder mit der Meldung " Gut genug Plan gefunden" oder mit einer Zeitüberschreitung . Beides sind Heuristiken, um zu verhindern, dass der Optimierer mehr Zeit für die Optimierung aufbringt, als er durch die Reduzierung der geschätzten Ausführungszeit (Kosten) gewinnen kann.
Testen
Es gibt keine unterstützte Möglichkeit, einen parallelen Plan zu erfordern, aber es gibt einige undokumentierte Tricks (nicht für die Produktion geeignet). Eine besteht darin, die während der Optimierung verwendete CPU-Gewichtung vorübergehend viel höher einzustellen, und die andere darin, das Ablaufverfolgungsflag 8649 zu setzen. Für SQL Server 2016 SP1 CU2 und höher führt der undokumentierte Abfragehinweis
OPTION (USE HINT ('ENABLE_PARALLEL_PLAN_PREFERENCE'))
dieselbe Funktion wie TF 8649 aus, jedoch ohne dass dies erforderlich ist Administratorrechte.Der erstellte Plan ist möglicherweise nicht der Plan, den das Optimierungsprogramm normalerweise in Betracht zieht. Sie können ihn jedoch möglicherweise erfassen und nach sorgfältigen Tests und Überprüfungen in einem Planleitfaden für die Produktion verwenden.
Weitere Informationen finden Sie in meinem Artikel Erzwingen eines Ausführungsplans für parallele Abfragen und nicht parallelisierbare Vorgänge in SQL Server von Simon Sabin.
quelle