Ved at undersøge Matts kommentar har jeg revideret min oprindelige udtalelse. Han har ret, der vil være en forskel i ydeevne mellem en inline table-valued function (ITVF) og en multi-statement table valued funktion (MSTVF), selvom de begge blot udfører en SELECT-sætning. SQL Server vil behandle en ITVF lidt som en VIEW
ved, at den vil beregne en udførelsesplan ved hjælp af den seneste statistik på de pågældende tabeller. En MSTVF svarer til at fylde hele indholdet af din SELECT-sætning i en tabelvariabel og derefter slutte sig til den. Compileren kan således ikke bruge nogen tabelstatistik på tabellerne i MSTVF. Så alt andet lige (hvilket de sjældent er), vil ITVF præstere bedre end MSTVF. I mine test var præstationsforskellen i færdiggørelsestid ubetydelig, men fra et statistisk synspunkt var den mærkbar.
I dit tilfælde er de to funktioner ikke funktionelt ækvivalente. MSTV-funktionen laver en ekstra forespørgsel hver gang den kaldes og, vigtigst af alt, filtrerer den på kunde-id'et. I en stor forespørgsel ville optimeringsværktøjet ikke være i stand til at drage fordel af andre typer joinforbindelser, da det ville være nødvendigt at kalde funktionen for hvert kunde-id, der er bestået. Men hvis du omskrev din MSTV-funktion sådan:
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 forespørgsel ville optimeringsværktøjet være i stand til at kalde denne funktion én gang og opbygge en bedre udførelsesplan, men den ville stadig ikke være bedre end en tilsvarende, ikke-parametriseret ITVS eller en VIEW
.
ITVF'er bør foretrækkes frem for en MSTVF'er, når det er muligt, fordi datatyperne, nullabiliteten og sammenstillingen fra kolonnerne i tabellen, hvorimod du erklærer disse egenskaber i en multi-sætningstabel værdisat funktion, og vigtigst af alt vil du få bedre udførelsesplaner fra ITVF. Efter min erfaring har jeg ikke fundet mange omstændigheder, hvor en ITVF var en bedre mulighed end en VIEW, men kilometertal kan variere.
Tak til Matt.
Tilføjelse
Siden jeg så dette komme op for nylig, er her en fremragende analyse udført af Wayne Sheffield, der sammenligner præstationsforskellen mellem Inline Table Valued-funktioner og Multi-Statement-funktioner.
Hans oprindelige blogindlæg.
Kopier på SQL Server Central