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

Funzione con valori di tabella a più istruzioni vs Funzione con valori di tabella inline

Nella ricerca del commento di Matt, ho rivisto la mia affermazione originale. Ha ragione, ci sarà una differenza di prestazioni tra una funzione con valori di tabella inline (ITVF) e una funzione con valori di tabella a più istruzioni (MSTVF) anche se entrambi eseguono semplicemente un'istruzione SELECT. SQL Server tratterà un ITVF in qualche modo come un VIEW in quanto calcolerà un piano di esecuzione utilizzando le ultime statistiche sulle tabelle in questione. Un MSTVF equivale a inserire l'intero contenuto della tua istruzione SELECT in una variabile di tabella e quindi unirti a quella. Pertanto, il compilatore non può utilizzare alcuna statistica di tabella nelle tabelle nell'MSTVF. Quindi, a parità di condizioni (cosa che raramente è), l'ITVF funzionerà meglio dell'MSTVF. Nei miei test, la differenza di prestazioni nel tempo di completamento era trascurabile, tuttavia da un punto di vista statistico era evidente.

Nel tuo caso, le due funzioni non sono funzionalmente equivalenti. La funzione MSTV esegue una query aggiuntiva ogni volta che viene chiamata e, soprattutto, filtra l'ID cliente. In una query di grandi dimensioni, l'ottimizzatore non sarebbe in grado di sfruttare altri tipi di join poiché dovrebbe chiamare la funzione per ogni customerId passato. Tuttavia, se hai riscritto la tua funzione MSTV in questo modo:

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

In una query, l'ottimizzatore sarebbe in grado di chiamare quella funzione una volta e costruire un piano di esecuzione migliore, ma non sarebbe comunque migliore di un ITVS equivalente, non parametrizzato o di un VIEW .

Gli ITVF dovrebbero essere preferiti a un MSTVF quando fattibile perché i tipi di dati, i valori Null e le regole di confronto dalle colonne della tabella mentre dichiari tali proprietà in una funzione valutata in una tabella con più istruzioni e, soprattutto, otterrai piani di esecuzione migliori dall'ITVF. Nella mia esperienza, non ho trovato molte circostanze in cui un ITVF fosse un'opzione migliore di un VIEW, ma il chilometraggio può variare.

Grazie a Matt.

Aggiunta

Dato che l'ho visto di recente, ecco un'eccellente analisi fatta da Wayne Sheffield che confronta la differenza di prestazioni tra le funzioni Inline Table Valued e le funzioni Multi-Statement.

Il suo post originale sul blog.

Copia su SQL Server Central