Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Função com valor de tabela de várias instruções vs função com valor de tabela em linha


Ao pesquisar o comentário de Matt, revisei minha declaração original. Ele está correto, haverá uma diferença no desempenho entre uma função com valor de tabela em linha (ITVF) e uma função com valor de tabela de várias instruções (MSTVF), mesmo que ambas simplesmente executem uma instrução SELECT. O SQL Server tratará um ITVF como um VIEW na medida em que calculará um plano de execução usando as estatísticas mais recentes das tabelas em questão. Um MSTVF é equivalente a colocar todo o conteúdo de sua instrução SELECT em uma variável de tabela e depois juntar-se a ela. Assim, o compilador não pode usar nenhuma estatística de tabela nas tabelas no MSTVF. Portanto, todas as coisas sendo iguais (o que raramente são), o ITVF terá um desempenho melhor que o MSTVF. Em meus testes, a diferença de desempenho no tempo de conclusão foi insignificante, mas do ponto de vista estatístico, foi perceptível.

No seu caso, as duas funções não são funcionalmente equivalentes. A função MSTV faz uma consulta extra cada vez que é chamada e, mais importante, filtra o ID do cliente. Em uma consulta grande, o otimizador não poderá tirar proveito de outros tipos de junções, pois precisaria chamar a função para cada customerId passado. No entanto, se você reescreveu sua função MSTV assim:
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

Em uma consulta, o otimizador seria capaz de chamar essa função uma vez e construir um plano de execução melhor, mas ainda não seria melhor do que um ITVS não parametrizado equivalente ou um VIEW .

Os ITVFs devem ser preferidos aos MSTVFs quando possível porque os tipos de dados, a nulidade e o agrupamento das colunas na tabela enquanto você declara essas propriedades em uma função com valor de tabela de várias instruções e, mais importante, você obterá melhores planos de execução do ITVF. Na minha experiência, não encontrei muitas circunstâncias em que um ITVF fosse uma opção melhor do que um VIEW, mas a quilometragem pode variar.

Graças a Matt.

Adição

Como vi isso recentemente, aqui está uma excelente análise feita por Wayne Sheffield comparando a diferença de desempenho entre funções Inline Table Valued e funções Multi-Statement.

Sua postagem original no blog.

Copiar no SQL Server Central