Khi nghiên cứu nhận xét của Matt, tôi đã sửa lại tuyên bố ban đầu của mình. Anh ấy đúng, sẽ có sự khác biệt về hiệu suất giữa hàm có giá trị trong bảng nội tuyến (ITVF) và hàm có giá trị trong bảng nhiều câu lệnh (MSTVF) ngay cả khi cả hai chỉ đơn giản thực hiện một câu lệnh SELECT. SQL Server sẽ coi ITVF giống như một VIEW
trong đó nó sẽ tính toán một kế hoạch thực hiện bằng cách sử dụng số liệu thống kê mới nhất trên các bảng được đề cập. MSTVF tương đương với việc nhồi toàn bộ nội dung của câu lệnh SELECT của bạn vào một biến bảng và sau đó kết hợp với biến đó. Do đó, trình biên dịch không thể sử dụng bất kỳ thống kê bảng nào trên các bảng trong MSTVF. Vì vậy, tất cả những điều bình đẳng, (hiếm khi xảy ra), ITVF sẽ hoạt động tốt hơn MSTVF. Trong các thử nghiệm của tôi, sự khác biệt về hiệu suất trong thời gian hoàn thành là không đáng kể tuy nhiên từ quan điểm thống kê, điều đó là đáng chú ý.
Trong trường hợp của bạn, hai chức năng không tương đương về mặt chức năng. Hàm MSTV thực hiện thêm một truy vấn mỗi khi nó được gọi và quan trọng nhất là lọc id khách hàng. Trong một truy vấn lớn, trình tối ưu hóa sẽ không thể tận dụng các kiểu kết hợp khác vì nó sẽ cần gọi hàm cho mỗi customerId được chuyển qua. Tuy nhiên, nếu bạn đã viết lại hàm MSTV của mình như vậy:
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
Trong một truy vấn, trình tối ưu hóa có thể gọi hàm đó một lần và xây dựng một kế hoạch thực thi tốt hơn nhưng nó vẫn sẽ không tốt hơn một ITVS tương đương, không tham số hoặc một VIEW
.
Các ITVF nên được ưu tiên hơn MSTVF khi khả thi vì các kiểu dữ liệu, khả năng vô hiệu và đối chiếu từ các cột trong bảng trong khi bạn khai báo các thuộc tính đó trong một hàm có giá trị bảng nhiều câu lệnh và quan trọng là bạn sẽ nhận được các kế hoạch thực thi tốt hơn từ ITVF. Theo kinh nghiệm của tôi, tôi không tìm thấy nhiều trường hợp mà ITVF là một lựa chọn tốt hơn một XEM nhưng quãng đường có thể thay đổi.
Cảm ơn Matt.
Bổ sung
Vì tôi thấy điều này mới xuất hiện gần đây, nên đây là một phân tích tuyệt vời do Wayne Sheffield thực hiện so sánh sự khác biệt về hiệu suất giữa các hàm Inline Table Valued và các hàm Multi-Statement.
Bài đăng trên blog gốc của anh ấy.
Sao chép trên SQL Server Central