Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Bảng nhiều câu lệnh Hàm có giá trị so với Hàm được định giá trong bảng nội tuyến

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Các rủi ro phổ biến của máy chủ SQL

  2. Công dụng của dấu ngoặc vuông [] trong câu lệnh sql là gì?

  3. Nhận ID hàng được chèn cuối cùng (với câu lệnh SQL)

  4. Cách ghi lại cơ sở dữ liệu SQL Server của bạn

  5. Làm cách nào để bạn đặt tự động gửi trong một phiên SQL Server?