sql >> Base de Datos >  >> RDS >> Sqlserver

Función con valor de tabla de varias instrucciones frente a función con valor de tabla en línea

Al investigar el comentario de Matt, revisé mi declaración original. Tiene razón, habrá una diferencia en el rendimiento entre una función con valores de tabla en línea (ITVF) y una función con valores de tabla de múltiples instrucciones (MSTVF), incluso si ambas simplemente ejecutan una instrucción SELECT. SQL Server tratará un ITVF como un VIEW ya que calculará un plan de ejecución utilizando las últimas estadísticas de las tablas en cuestión. Un MSTVF es equivalente a rellenar todo el contenido de su declaración SELECT en una variable de tabla y luego unirse a eso. Por lo tanto, el compilador no puede usar ninguna estadística de tabla en las tablas de MSTVF. Entonces, en igualdad de condiciones (que rara vez lo son), la ITVF funcionará mejor que la MSTVF. En mis pruebas, la diferencia de rendimiento en el tiempo de finalización fue insignificante; sin embargo, desde el punto de vista de las estadísticas, fue notable.

En su caso, las dos funciones no son funcionalmente equivalentes. La función MSTV realiza una consulta adicional cada vez que se llama y, lo que es más importante, filtra la identificación del cliente. En una consulta grande, el optimizador no podría aprovechar otros tipos de uniones, ya que necesitaría llamar a la función para cada ID de cliente pasado. Sin embargo, si reescribió su función MSTV así:

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

En una consulta, el optimizador podría llamar a esa función una vez y crear un mejor plan de ejecución, pero aún así no sería mejor que un ITVS equivalente, no parametrizado o un VIEW .

Los ITVF deben preferirse a los MSTVF cuando sea factible debido a los tipos de datos, la nulabilidad y la intercalación de las columnas en la tabla, mientras que usted declara esas propiedades en una función de valor de tabla de múltiples declaraciones y, lo que es más importante, obtendrá mejores planes de ejecución del ITVF. En mi experiencia, no he encontrado muchas circunstancias en las que una ITVF fuera una mejor opción que una VISTA, pero el kilometraje puede variar.

Gracias a Matt.

Adición

Como vi que esto surgió recientemente, aquí hay un excelente análisis realizado por Wayne Sheffield que compara la diferencia de rendimiento entre las funciones de valores de tabla en línea y las funciones de declaraciones múltiples.

Su publicación de blog original.

Copiar en SQL Server Central