E nada sobre as funções. Por que as informações de função estão ausentes no plano real?
Isso ocorre por design, por razões de desempenho.
As funções que contêm BEGIN
e END
na definição criam um novo quadro de pilha T-SQL para cada linha de entrada. Em outras palavras, o corpo da função é executado separadamente para cada linha de entrada . Esse fato único explica a maioria dos problemas de desempenho associados às funções escalares e de múltiplas instruções T-SQL (observe que as funções com valor de tabela em linha não usam a BEGIN...END
sintaxe).
No contexto da sua pergunta, isso resultaria em SHOWPLAN
saída completa para cada linha. A saída do plano XML é bastante detalhada e cara de produzir, portanto, produzir uma saída completa para cada linha seria uma má idéia em termos gerais.
Exemplo
Considere a função escalar T-SQL abaixo, criada no banco de dados de exemplo AdventureWorks , que retorna o nome de um produto com seu ID:
CREATE FUNCTION dbo.DumbNameLookup
(
@ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
RETURN
(
SELECT
p.Name
FROM Production.Product AS p
WHERE
p.ProductID = @ProductID
);
END;
Plano de pré-execução
Um plano de pré-execução (plano estimado no SSMS) mostra informações de plano para a instrução pai e chamadas de função aninhadas:
-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;
Saída SSMS:
O mesmo XML exibido no SQL Sentry Plan Explorer mostra a natureza aninhada das chamadas com mais clareza:
Saída pós-execução
O SSMS mostra detalhes apenas da consulta principal quando a saída do plano pós-execução é solicitada:
-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;
O impacto no desempenho de fazer o contrário pode ser mostrado usando a classe de evento Showplan XML Statistics Profile no SQL Server Profiler, usando uma consulta que chama a função várias vezes (uma vez por linha de entrada):
SELECT TOP (5)
p.ProductID,
dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;
Saída do Profiler:
Existem cinco planos de pós-execução separados para as execuções de funções e um para a consulta pai. Os cinco planos de função se parecem com isso no painel inferior do criador de perfil:
O plano de consulta pai é:
A execução da consulta sem a TOP (5)
cláusula resulta em um plano de execução completo para cada uma das 504 linhas da tabela Produto. Provavelmente, você pode ver como isso rapidamente sairia do controle com tabelas maiores.
A situação dos gatilhos é revertida. Eles não mostram nenhuma informação do plano de pré-execução, mas incluem um plano de pós-execução. Isso reflete a natureza baseada em conjunto dos gatilhos; cada um é acionado uma vez para todas as linhas afetadas, em vez de uma vez por linha.