Desempenho de Inline-TVF x visualizações

9

Eu tenho um banco de dados onde estou usando TVFs embutidos (funções de valor de tabela) em vez de visualizações. Por exemplo, eu posso ter duas tabelas chamadas [modelo de carro] e [fabricante de carro] que estou juntando dentro do TVF [fnCarBrands].

Esses TVFs são chamados por outros TVFs para processar e gerar relatórios adicionais. Portanto, posso pegar minha função [fnCarBrands] e me juntar à tabela [Ano da compra] para formar uma função [fnCarBrandHistory]. E assim por diante para várias camadas de TVFs.

Provavelmente eu poderia obter a mesma funcionalidade usando visualizações, pois meus TVFs embutidos são na verdade apenas junções de tabelas e outros TVFs.

Como o desempenho dos TVFs incorporados dessa maneira se compara às visualizações?

FistOfFury
fonte
Provavelmente você veria os mesmos planos de execução e o mesmo desempenho.
AK
foi o que pensei, mas me disseram que o TVF age como um parêntese na álgebra - força o mecanismo DB a concluir essa consulta antes de otimizar. O uso de visualizações, disseram, permite que o otimizador otimize toda a consulta como uma unidade.
FistOfFury
Uma espécie de nota lateral, mas alguma idéia de por que os TVFs foram usados ​​em vez de visualizações? Apenas abordagem de código-macaco vs macaco de dados para o problema?
Mark-Storey-Smith
@ MarkStorey-Smith sim, o motivo é como você diz, abordagem código-macaco vs macaco de dados.
FistOfFury 15/08

Respostas:

12

O otimizador de consultas trata uma função com valor de tabela embutida exatamente como uma exibição:

CREATE FUNCTION dbo.InlineUdf(@arg1 int)
RETURNS TABLE
AS
RETURN 
(
    ... your query here ...
);

Uma função com valor de tabela com várias instruções é executada mais como um procedimento armazenado. Eles geralmente precisam ser executados várias vezes, em vez de serem dobrados na consulta principal:

CREATE FUNCTION dbo.MultiStatementUdf (@col1 int)
RETURNS @result TABLE 
(
    id int primary key NOT NULL,
    ... 
)
AS
BEGIN
   DECLARE @var1 int
   set @var1 = 42

   INSERT @result
   SELECT ...
   RETURN
END;
Andomar
fonte
11
@Andomar, meu entendimento é que os TVFs com várias instruções são executados como uma caixa preta, o mecanismo não sabe o que está nele e não pode otimizar a consulta. Você tem algum artigo que possa referenciar que diga que visualizações e TVFs embutidos são equivalentes?
FistOfFury
4

Você precisará criar visualizações semelhantes às funções e consultar cada uma olhando o plano de execução para ver o que está acontecendo com cada uma.

Mrdenny
fonte
Exatamente. Benchmarking, vendo por si mesmo - esta é a única maneira confiável de aprender.
AK
@mrdenny Não há como prever como o otimizador tratará cada tipo de consulta? Certamente existem algumas regras a seguir.
FistOfFury
2
@FistOfFury Sim, existem regras, milhares e milhares delas, complementadas com centenas de anos de desenvolvedor de código heurístico. É por isso que você terá que testar ou pedir à Microsoft o código-fonte do otimizador.
Mark-Storey-Smith
Se você faria melhor como para entender como o mecanismo de banco de dados determina o que fazer, então você precisa ler sobre SQL Server internas, amazon.com/s/...
HLGEM
3

É claro que criar visões que chamam outras visões também é prejudicial ao desempenho. Não siga por esse caminho. Escreva as consultas necessárias e não use TVFs ou exibições se desejar desempenho. São as camadas que estão criando o problema, isso quase sempre é uma coisa ruim a se fazer ao consultar um banco de dados e você pode acabar rapidamente atingindo o limite do número de tabelas às quais pode se referir também, especialmente porque muitas vezes acaba fazendo referência ao mesmas tabelas em diferentes camadas. Além disso, embora isso pareça mais fácil de manter, não é. Tente depurar ou adicionar uma coluna devido a um novo requisito quando a camada que você precisa corrigir estiver na parte inferior.

HLGEM
fonte