Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Tabela z wieloma wyrażeniami Wartości funkcji w porównaniu z tabelą inline Wartości funkcji

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 4 wskazówki dotyczące konfigurowania alertów serwera SQL

  2. Poznaj bazę danych przywracania SQL Server z odzyskiwaniem i bez opcji odzyskiwania

  3. Co to jest ciąg formatujący w programie SQL Server?

  4. Dodawanie wielu sparametryzowanych zmiennych do bazy danych w c#

  5. Błąd SQL Server 4104:Nie można powiązać wieloczęściowego identyfikatora.