Welche Regeln bestimmen, wann SQL Server einen CTE als „Optimierungszaun“ verwendet?

10

Vor einiger Zeit veröffentlichte Brent Ozar einen Beitrag, in dem einige der Unterschiede zwischen SQL Server und PostgreSQL beschrieben wurden:

Zwei wichtige Unterschiede zwischen SQL Server und PostgreSQL

Der erste Punkt („CTEs sind Optimierungszäune“) ist mir aufgefallen, da es offensichtlich ist, dass SQL Server im bereitgestellten Beispiel den CTE und die Hauptabfrage miteinander kombiniert und als einzelne Abfrage optimiert (im Gegensatz zum entgegengesetzten Verhalten in PostgreSQL).

Dieses Verhalten scheint jedoch den Beispielen zu widersprechen, die ich in anderen Blogs und Schulungsklassen gesehen habe, in denen SQL Server den CTE als Optimierungszaun behandelt, der eine bessere Verwendung von Indizes, eine bessere Leistung usw. ermöglicht. Zum Beispiel:

Ein besserer Weg, um Stern auszuwählen

Es scheint also, als würde SQL Server den CTE manchmal als Optimierungszaun „ehren“. Gibt es gute Ressourcen, die die spezifische Liste bekannter Fälle dokumentieren, in denen SQL Server den CTE zuverlässig als Optimierungszaun (oder das entgegengesetzte Verhalten) anerkennt?

Bryan Rebok
quelle

Antworten:

10

... Liste bekannter Fälle, in denen SQL Server den CTE als Optimierungszaun zuverlässig anerkennt

Eine solche Liste würde sich auf das beobachtete Verhalten stützen, ohne Gewähr für die Zuverlässigkeit.

Das SQL Server-Abfrageoptimierungsprogramm behandelt einen allgemeinen Tabellenausdruck niemals als Optimierungszaun an sich , obwohl einige Konstruktionen eindeutig schwer zu optimieren sind. Rekursive CTEs sind ein gutes Beispiel dafür.

CTEs werden sehr ähnlich wie Ansichten / Inline-Funktionen / Unterabfragen / abgeleitete Tabellen behandelt und in die Abfrage eingefügt. Jedes beobachtete "Zaun" -Verhalten hängt davon ab, dass der Optimierer entweder nicht in der Lage ist oder sich dafür entscheidet, nicht über diese im Prinzip durchlässige Grenze hinweg zu optimieren.

Im Allgemeinen ist es umso wahrscheinlicher, dass der Optimierer Bits verschieben kann, je einfacher und relationaler der CTE ist.

Funktionen, die es dem Optimierer ermöglichen würden, das "Ergebnis" eines CTE zu berücksichtigen oder zu erzwingen, wurden vorgeschlagen, aber noch nicht implementiert:

In der Zwischenzeit besteht die häufigste Problemumgehung darin, die Zwischenergebnismenge in einer temporären Tabelle oder Tabellenvariablen explizit zu materialisieren. Dies erfordert offensichtlich ein Szenario, das nicht auf eine einzelne Anweisung beschränkt ist.

Paul White 9
quelle