sql >> Database teknologi >  >> RDS >> Sqlserver

Multi-sætning tabel værdisat funktion vs inline tabel værdisat funktion

Ved at undersøge Matts kommentar har jeg revideret min oprindelige udtalelse. Han har ret, der vil være en forskel i ydeevne mellem en inline table-valued function (ITVF) og en multi-statement table valued funktion (MSTVF), selvom de begge blot udfører en SELECT-sætning. SQL Server vil behandle en ITVF lidt som en VIEW ved, at den vil beregne en udførelsesplan ved hjælp af den seneste statistik på de pågældende tabeller. En MSTVF svarer til at fylde hele indholdet af din SELECT-sætning i en tabelvariabel og derefter slutte sig til den. Compileren kan således ikke bruge nogen tabelstatistik på tabellerne i MSTVF. Så alt andet lige (hvilket de sjældent er), vil ITVF præstere bedre end MSTVF. I mine test var præstationsforskellen i færdiggørelsestid ubetydelig, men fra et statistisk synspunkt var den mærkbar.

I dit tilfælde er de to funktioner ikke funktionelt ækvivalente. MSTV-funktionen laver en ekstra forespørgsel hver gang den kaldes og, vigtigst af alt, filtrerer den på kunde-id'et. I en stor forespørgsel ville optimeringsværktøjet ikke være i stand til at drage fordel af andre typer joinforbindelser, da det ville være nødvendigt at kalde funktionen for hvert kunde-id, der er bestået. Men hvis du omskrev din MSTV-funktion sådan:

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 forespørgsel ville optimeringsværktøjet være i stand til at kalde denne funktion én gang og opbygge en bedre udførelsesplan, men den ville stadig ikke være bedre end en tilsvarende, ikke-parametriseret ITVS eller en VIEW .

ITVF'er bør foretrækkes frem for en MSTVF'er, når det er muligt, fordi datatyperne, nullabiliteten og sammenstillingen fra kolonnerne i tabellen, hvorimod du erklærer disse egenskaber i en multi-sætningstabel værdisat funktion, og vigtigst af alt vil du få bedre udførelsesplaner fra ITVF. Efter min erfaring har jeg ikke fundet mange omstændigheder, hvor en ITVF var en bedre mulighed end en VIEW, men kilometertal kan variere.

Tak til Matt.

Tilføjelse

Siden jeg så dette komme op for nylig, er her en fremragende analyse udført af Wayne Sheffield, der sammenligner præstationsforskellen mellem Inline Table Valued-funktioner og Multi-Statement-funktioner.

Hans oprindelige blogindlæg.

Kopier på SQL Server Central



  1. Brug af regex i WHERE i Postgres

  2. At køre SQL-script gennem psql giver syntaksfejl, der ikke forekommer i PgAdmin

  3. Sådan forbinder du en database til Python

  4. Forbedre SQL Server-forespørgselsydeevne på store tabeller