Bei der Untersuchung von Matts Kommentar habe ich meine ursprüngliche Aussage revidiert. Er hat Recht, es gibt einen Leistungsunterschied zwischen einer Inline-Tabellenwertfunktion (ITVF) und einer Multi-Statement-Tabellenwertfunktion (MSTVF), selbst wenn beide einfach eine SELECT-Anweisung ausführen. SQL Server behandelt eine ITVF in etwa wie eine VIEW
, dass es anhand der neuesten Statistiken zu den betreffenden Tischen einen Ausführungsplan berechnet. Ein MSTVF entspricht dem Füllen des gesamten Inhalts Ihrer SELECT-Anweisung in eine Tabellenvariable und dem anschließenden Verbinden mit dieser. Daher kann der Compiler keine Tabellenstatistiken für die Tabellen in der MSTVF verwenden. Wenn also alle Dinge gleich sind (was selten der Fall ist), wird der ITVF besser abschneiden als der MSTVF. In meinen Tests war der Leistungsunterschied in der Ausführungszeit vernachlässigbar, aus statistischer Sicht jedoch auffällig.
In Ihrem Fall sind die beiden Funktionen nicht funktional gleichwertig. Die MSTV-Funktion führt bei jedem Aufruf eine zusätzliche Abfrage durch und filtert vor allem nach der Kunden-ID. In einer großen Abfrage wäre der Optimierer nicht in der Lage, andere Join-Typen zu nutzen, da er die Funktion für jede übergebene Kunden-ID aufrufen müsste. Wenn Sie jedoch Ihre MSTV-Funktion wie folgt neu geschrieben haben:
CREATE FUNCTION MyNS.GetLastShipped()
RETURNS @CustomerOrder TABLE
(
SaleOrderID INT NOT NULL,
CustomerID INT NOT NULL,
OrderDate DATETIME NOT NULL,
OrderQty INT NOT NULL
)
AS
BEGIN
INSERT @CustomerOrder
SELECT a.SalesOrderID, a.CustomerID, a.OrderDate, b.OrderQty
FROM Sales.SalesOrderHeader a
INNER JOIN Sales.SalesOrderHeader b
ON a.SalesOrderID = b.SalesOrderID
INNER JOIN Production.Product c
ON b.ProductID = c.ProductID
WHERE a.OrderDate = (
Select Max(SH1.OrderDate)
FROM Sales.SalesOrderHeader As SH1
WHERE SH1.CustomerID = A.CustomerId
)
RETURN
END
GO
In einer Abfrage könnte der Optimierer diese Funktion einmal aufrufen und einen besseren Ausführungsplan erstellen, aber er wäre immer noch nicht besser als ein gleichwertiges, nicht parametrisiertes ITVS oder ein VIEW
.
ITVFs sollten gegenüber MSTVFs bevorzugt werden, wenn dies möglich ist, da die Datentypen, die Nullzulässigkeit und die Sortierung aus den Spalten in der Tabelle, während Sie diese Eigenschaften in einer Tabellenwertfunktion mit mehreren Anweisungen deklarieren, und, was wichtig ist, Sie bessere Ausführungspläne vom ITVF erhalten. Nach meiner Erfahrung habe ich nicht viele Umstände gefunden, in denen ein ITVF eine bessere Option als ein VIEW war, aber die Laufleistung kann variieren.
Danke an Matt.
Zusatz
Da ich dies kürzlich gesehen habe, ist hier eine ausgezeichnete Analyse von Wayne Sheffield, die den Leistungsunterschied zwischen Inline-Tabellenwertfunktionen und Multi-Statement-Funktionen vergleicht.
Sein ursprünglicher Blogbeitrag.
Kopieren Sie auf SQL Server Central