Ich bin auf eine Frage wie diese gestoßen:
SELECT (SELECT COUNT(1) FROM Orders o WHERE i.ItemId = o.ItemId) [C]
FROM Items i
Ich habe es in folgendes geändert
;WITH cte_count
AS
(
SELECT COUNT(1) c, OrderId FROM Orders Group By ItemId
)
SELECT a.c [Count], i.Name
FROM Items i
INNER JOIN cte_count c ON (c.ItemId = i.ItemId)
Der Ausführungsplan für beide ist jedoch der gleiche wie unten gezeigt:
Ebenso wurde eine andere Abfrage ausgewählt TOP 1 Order By Id
. Ich habe versucht, dieses zu verschieben. CROSS APPLY
Aber auch für dieses habe ich die gleichen Ausführungspläne.
Natürlich gab es andere Verknüpfungen und Spalten in der Abfrage.
In meinem Dilemma geht es um Nutzen und Vorteile der Verwendung von CROSS APPLY
und CTE
. Gibt es welche oder nur exotische?
t-sql
subquery
cte
cross-apply
TheVillageIdiot
quelle
quelle
Antworten:
Die Pläne sind unterschiedlich. Eine ist eine innere Verbindung, die andere ist eine äußere Verbindung. Die Ergebnisse in Ihrem einfachen Test mögen gleich sein, aber die Semantik ist unterschiedlich. Bei komplexeren Abfragen kann der Unterschied offensichtlich zu unterschiedlichen Ausführungsplänen führen und sich auf die Leistung auswirken.
Es gibt normalerweise viele Möglichkeiten, dieselbe Anforderung (oder eine ähnliche Anforderung wie in Ihrem Beispiel) in SQL auszudrücken. Was Sie verwenden, ist zunächst eine Frage der Präferenz und des Stils. In einigen Fällen führt die Verwendung des einen oder anderen zu wichtigen Leistungsunterschieden, da das deklarative SQL einen anderen Codepfad durch das Optimierungsprogramm verwendet. In diesem speziellen Fall spielt die äußere Verknüpfung möglicherweise weniger gut mit den Erkundungsfähigkeiten des Optimierers (es stehen weniger Werkzeuge für äußere Verknüpfungen als für innere Verknüpfungen zur Verfügung).
Das Umschreiben einer Abfrage, um dieselben Ergebnisse mit unterschiedlicher Syntax zu definieren, kann eine gültige Optimierungsmethode sein. Sie erfordert jedoch sorgfältige Detailgenauigkeit und erneutes Testen, wenn SQL Server gepatcht oder aktualisiert wird. Es gibt im Allgemeinen keinen Grund, eine Möglichkeit, eine Anforderung in SQL auszudrücken, einer anderen vorzuziehen.
Wie Andriy in einem Kommentar zu der anderen Kopie Ihrer Frage erwähnt hat, "erhalten Sie im allgemeineren Fall bei Ihren Inline-Abfragen nur ein Ergebnis pro Zeile, während Sie einem CTE beitreten (der kein a sein muss) CTE (es könnte sich um eine normale Unterauswahl handeln) oder CROSS, wenn Sie einen Zeilensatz anwenden, können Sie auf mehr als eine Spalte zugreifen. "
quelle
Bei kleinen Datenmengen kümmert sich der Optimierer wahrscheinlich nicht um umfangreiche Analysen. Wenn Sie sich jedoch konkurrierende Pläne für große Datenmengen ansehen (z. B. Millionen von Bestellungen oder Artikeln aus Ihrem Beispiel), wird CROSS APPLY, insbesondere wenn Artikel indiziert sind, schneller ausgeführt.
Sicher. Wenn es einen Unterschied gegeben hätte, hätten sich die Pläne gezeigt. Darüber hinaus würden Sie bei der Ausführung definitiv Leistungsunterschiede feststellen.
quelle
Was ist, wenn du es tust?
cte
undapply
hat seine Vorteile in einigen Fällen, ich bin sicher, nur wahrscheinlich nicht einfache Fälle wie dieseIch verwende ein
cte
hauptsächlich aus ästhetischen Gründen, wenn ich versuche, einen visuellen Fluss zu erzeugen, wie ich größere Ergebnisse in kleinere zerlege, um die endgültige Abfrage zu erstellen und natürlich zu rekursieren.apply
ist ziemlich cool, wenn Sie eine Tabellenwertfunktion verwenden, die einen Parameterwert aus der vorherigen Tabelle übernimmt.cross apply
kann schöner sein als einefull join
Aussage.Wenn Sie wissen, wonach Sie in einem Abfrageplan suchen, ist dies vermutlich nur eine Frage der Präferenz
quelle