När jag undersökte Matts kommentar har jag reviderat mitt ursprungliga uttalande. Han har rätt, det kommer att finnas en skillnad i prestanda mellan en inline table valued function (ITVF) och en multi-statement table valued funktion (MSTVF) även om de båda bara kör en SELECT-sats. SQL Server kommer att behandla en ITVF ungefär som en VIEW
genom att den kommer att beräkna en genomförandeplan med hjälp av den senaste statistiken för de aktuella tabellerna. En MSTVF motsvarar att stoppa in hela innehållet i din SELECT-sats i en tabellvariabel och sedan ansluta till den. Således kan kompilatorn inte använda någon tabellstatistik på tabellerna i MSTVF. Så, allt annat lika, (vilket de sällan är), kommer ITVF att prestera bättre än MSTVF. I mina tester var prestandaskillnaden i färdigställandetid försumbar, men ur statistiksynpunkt var den märkbar.
I ditt fall är de två funktionerna inte funktionellt likvärdiga. MSTV-funktionen gör en extra fråga varje gång den anropas och, viktigast av allt, filtrerar på kund-ID. I en stor fråga skulle optimeraren inte kunna dra fördel av andra typer av joins eftersom den skulle behöva anropa funktionen för varje kund-ID som passerats. Men om du skrev om din MSTV-funktion så här:
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
I en fråga skulle optimeraren kunna anropa den funktionen en gång och bygga en bättre exekveringsplan, men den skulle fortfarande inte vara bättre än en likvärdig, icke-parametriserad ITVS eller en VIEW
.
ITVF:er bör föredras framför MSTVF:er när det är möjligt eftersom datatyperna, nullbarheten och sammanställningen från kolumnerna i tabellen medan du deklarerar dessa egenskaper i en flersatstabell värderad funktion och, viktigare, du kommer att få bättre exekveringsplaner från ITVF. Enligt min erfarenhet har jag inte hittat många omständigheter där en ITVF var ett bättre alternativ än en VIEW men körsträckan kan variera.
Tack vare Matt.
Tillägg
Eftersom jag såg detta dyka upp nyligen, här är en utmärkt analys gjord av Wayne Sheffield som jämför prestandaskillnaden mellan Inline Table Valued-funktioner och Multi-Statement-funktioner.
Hans ursprungliga blogginlägg.
Kopiera på SQL Server Central