Badając komentarz Matta, zrewidowałem swoje oryginalne oświadczenie. Ma rację, będzie różnica w wydajności między wbudowaną funkcją o wartości tabeli (ITVF) a wieloinstrukcyjną funkcją o wartości tabeli (MSTVF), nawet jeśli obie po prostu wykonują instrukcję SELECT. SQL Server będzie traktował ITVF trochę jak VIEW
w ten sposób, że obliczy plan wykonania, korzystając z najnowszych statystyk dotyczących danych tabel. MSTVF jest równoważne upchaniu całej zawartości instrukcji SELECT do zmiennej tabeli, a następnie dołączeniu do niej. W związku z tym kompilator nie może używać żadnych statystyk tabel w tabelach w MSTVF. Tak więc, wszystkie rzeczy są równe (co rzadko się zdarza), ITVF będzie działać lepiej niż MSTVF. W moich testach różnica wydajności w czasie realizacji była znikoma, jednak z punktu widzenia statystyk była zauważalna.
W twoim przypadku te dwie funkcje nie są funkcjonalnie równoważne. Funkcja MSTV wykonuje dodatkowe zapytanie przy każdym wywołaniu i, co najważniejsze, filtruje identyfikator klienta. W przypadku dużego zapytania optymalizator nie byłby w stanie skorzystać z innych typów złączeń, ponieważ musiałby wywoływać funkcję dla każdego przekazanego identyfikatora klienta. Jeśli jednak zmieniłeś swoją funkcję MSTV w ten sposób:
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
W zapytaniu optymalizator byłby w stanie wywołać tę funkcję raz i zbudować lepszy plan wykonania, ale nadal nie byłby lepszy niż równoważny, niesparametryzowany ITVS lub VIEW
.
ITVF powinny być preferowane w stosunku do MSTVF, gdy jest to wykonalne, ponieważ typy danych, dopuszczalność wartości null i sortowanie z kolumn w tabeli, podczas gdy deklarujesz te właściwości w funkcji o wartościach w tabeli zawierającej wiele instrukcji i, co ważne, uzyskasz lepsze plany wykonania z ITVF. Z mojego doświadczenia wynika, że nie znalazłem wielu okoliczności, w których ITVF byłby lepszą opcją niż VIEW, ale przebieg może się różnić.
Dzięki Mattowi.
Dodanie
Ponieważ ostatnio zauważyłem, że to się pojawiło, oto doskonała analiza wykonana przez Wayne'a Sheffielda, porównująca różnicę wydajności między funkcjami o wartościach w tabeli śródliniowej a funkcjami z wieloma wyrażeniami.
Jego oryginalny wpis na blogu.
Kopiuj do SQL Server Central