Kein Vorteil der Verwendung von Cross Apply oder CTE gegenüber Inline-Unterabfragen


8

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:

CTE- und Inline-Ausführungsplan

Ebenso wurde eine andere Abfrage ausgewählt TOP 1 Order By Id. Ich habe versucht, dieses zu verschieben. CROSS APPLYAber auch für dieses habe ich die gleichen Ausführungspläne.

Cross Apply und Inline Execution Plan

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 APPLYund CTE. Gibt es welche oder nur exotische?



2
In einem allgemeineren Fall erhalten Sie mit Ihren Inline-Abfragen nur ein Ergebnis pro Zeile, während Sie sich einem CTE anschließen (der kein CTE sein muss, es könnte sich um eine normale Unterauswahl handeln) oder CROSS, das einen Zeilensatz anwendet, erhalten Zugriff auf mehr als eine Spalte.
Andriy M

Antworten:


21

Der Ausführungsplan für beide ist jedoch der gleiche wie unten gezeigt:

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. "


1

Mein Dilemma betrifft den Nutzen und die Vorteile der Verwendung von CROSS APPLY und CTE. Gibt es welche oder nur exotische?

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.

Darüber hinaus ist es sogar angebracht, dies anhand eines Ausführungsplans zu überprüfen.

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.


Was lässt Sie sagen, dass die CROSS APPLY schneller wäre?
Murphybro2

0

Was ist, wenn du es tust?

SELECT i.Name
       COUNT(o.OrderId) c
FROM   Items i
       JOIN Orders o ON i.ItemID = o.ItemID
GROUP BY i.ItemID

cteund applyhat seine Vorteile in einigen Fällen, ich bin sicher, nur wahrscheinlich nicht einfache Fälle wie diese

Ich verwende ein ctehauptsä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.

applyist ziemlich cool, wenn Sie eine Tabellenwertfunktion verwenden, die einen Parameterwert aus der vorherigen Tabelle übernimmt. cross applykann schöner sein als eine full joinAussage.

Wenn Sie wissen, wonach Sie in einem Abfrageplan suchen, ist dies vermutlich nur eine Frage der Präferenz


Nun, es ist nicht einfach, dass es auch andere Tabellenverknüpfungen und Spalten gibt. Ich verwende CTE und Cross / Outer Apply, anstatt Unterabfragen in die Auswahlliste oder wo Bedingungen zu setzen. Deshalb gab es einen ähnlichen Ausführungsplan, als ich diesen in CTE und Cross Apply konvertierte.
TheVillageIdiot
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.