sql >> Databasteknik >  >> RDS >> Sqlserver

Tabellvärderad funktion med flera påståenden vs inline-värderad tabellfunktion

När jag undersökte Matts kommentar har jag reviderat mitt ursprungliga uttalande. Han har rätt, det kommer att finnas en skillnad i prestanda mellan en inline table valued function (ITVF) och en multi-statement table valued funktion (MSTVF) även om de båda bara kör en SELECT-sats. SQL Server kommer att behandla en ITVF ungefär som en VIEW genom att den kommer att beräkna en genomförandeplan med hjälp av den senaste statistiken för de aktuella tabellerna. En MSTVF motsvarar att stoppa in hela innehållet i din SELECT-sats i en tabellvariabel och sedan ansluta till den. Således kan kompilatorn inte använda någon tabellstatistik på tabellerna i MSTVF. Så, allt annat lika, (vilket de sällan är), kommer ITVF att prestera bättre än MSTVF. I mina tester var prestandaskillnaden i färdigställandetid försumbar, men ur statistiksynpunkt var den märkbar.

I ditt fall är de två funktionerna inte funktionellt likvärdiga. MSTV-funktionen gör en extra fråga varje gång den anropas och, viktigast av allt, filtrerar på kund-ID. I en stor fråga skulle optimeraren inte kunna dra fördel av andra typer av joins eftersom den skulle behöva anropa funktionen för varje kund-ID som passerats. Men om du skrev om din MSTV-funktion så här:

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

I en fråga skulle optimeraren kunna anropa den funktionen en gång och bygga en bättre exekveringsplan, men den skulle fortfarande inte vara bättre än en likvärdig, icke-parametriserad ITVS eller en VIEW .

ITVF:er bör föredras framför MSTVF:er när det är möjligt eftersom datatyperna, nullbarheten och sammanställningen från kolumnerna i tabellen medan du deklarerar dessa egenskaper i en flersatstabell värderad funktion och, viktigare, du kommer att få bättre exekveringsplaner från ITVF. Enligt min erfarenhet har jag inte hittat många omständigheter där en ITVF var ett bättre alternativ än en VIEW men körsträckan kan variera.

Tack vare Matt.

Tillägg

Eftersom jag såg detta dyka upp nyligen, här är en utmärkt analys gjord av Wayne Sheffield som jämför prestandaskillnaden mellan Inline Table Valued-funktioner och Multi-Statement-funktioner.

Hans ursprungliga blogginlägg.

Kopiera på SQL Server Central



  1. Visual Basic för applikationer i Microsoft Access

  2. Vad är nytt i MariaDB MaxScale 2.4

  3. Hur man använder en ringdatastruktur i fönsterfunktioner

  4. Hur man aktiverar spårning i oracle apps r12