sql >> Databáze >  >> RDS >> Sqlserver

Vícepříkazová funkce s hodnotou tabulky vs. funkce s hodnotou s vloženou tabulkou

Při zkoumání Mattova komentáře jsem zrevidoval své původní tvrzení. Má pravdu, bude rozdíl ve výkonu mezi inline funkcí s hodnotou tabulky (ITVF) a funkcí s hodnotou s více příkazy (MSTVF), i když obě jednoduše provedou příkaz SELECT. SQL Server bude s ITVF zacházet podobně jako s VIEW tím, že vypočítá prováděcí plán s použitím nejnovějších statistik o příslušných tabulkách. MSTVF je ekvivalentní nacpání celého obsahu vašeho příkazu SELECT do proměnné tabulky a následnému připojení k ní. Kompilátor tedy nemůže použít žádné statistiky tabulek na tabulkách v MSTVF. Takže za předpokladu, že jsou všechny věci stejné (což zřídka jsou), bude ITVF fungovat lépe než MSTVF. V mých testech byl rozdíl ve výkonu v době dokončení zanedbatelný, ale z hlediska statistik byl znatelný.

Ve vašem případě nejsou tyto dvě funkce funkčně ekvivalentní. Funkce MSTV provede při každém zavolání další dotaz a, co je nejdůležitější, filtruje podle ID zákazníka. Ve velkém dotazu by optimalizátor nemohl využít výhody jiných typů spojení, protože by musel volat funkci pro každé předané customerId. Pokud však svou funkci MSTV přepíšete takto:

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

V dotazu by byl optimalizátor schopen zavolat tuto funkci jednou a vytvořit lepší plán provádění, ale stále by to nebylo lepší než ekvivalentní, neparametrizované ITVS nebo VIEW .

ITVF by měly být upřednostňovány před MSTVF, pokud je to možné, protože datové typy, možnost null a řazení ze sloupců v tabulce, zatímco tyto vlastnosti deklarujete ve vícepříkazové tabulce hodnotné funkce, a co je důležité, získáte lepší prováděcí plány z ITVF. Podle mých zkušeností jsem nenašel mnoho okolností, kdy by ITVF byla lepší volba než VIEW, ale počet najetých kilometrů se může lišit.

Díky Mattovi.

Přidání

Vzhledem k tomu, že jsem to nedávno viděl, zde je vynikající analýza provedená Waynem Sheffieldem, která porovnává rozdíl ve výkonu mezi funkcemi Inline Table Valued a funkcemi Multi-Statement.

Jeho původní příspěvek na blogu.

Kopírovat na SQL Server Central



  1. Vyhledejte konkrétní řetězec ve sloupci Oracle clob

  2. Jak vybrat pouze datum z pole DATETIME v MySQL?

  3. Vypočítejte časový rozdíl mezi dvěma řadami

  4. Looping Over Result Sets v MySQL