Y nada sobre las funciones. ¿Por qué falta la información de la función en el plan real?
Esto es por diseño, por razones de rendimiento.
Las funciones que contienen BEGIN
y END
en la definición crean un nuevo marco de pila T-SQL para cada fila de entrada. Dicho de otra manera, el cuerpo de la función se ejecuta por separado para cada fila de entrada . Este hecho único explica la mayoría de los problemas de rendimiento asociados con las funciones escalares y de múltiples instrucciones de T-SQL (tenga en cuenta que las funciones con valores de tabla en línea no utilizan la BEGIN...END
sintaxis).
En el contexto de su pregunta, esto daría como resultado una SHOWPLAN
salida completa para cada fila. La producción del plan XML es bastante detallada y costosa de producir, por lo que producir una producción completa para cada fila sería una mala idea en términos generales.
Ejemplo
Considere la siguiente función escalar T-SQL, creada en la base de datos de ejemplo AdventureWorks , que devuelve el nombre de un producto dada su 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;
Plan de preejecución
Un plan previo a la ejecución (plan estimado en SSMS) muestra información del plan para la declaración principal y las llamadas de función anidadas:
-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;
Salida SSMS:
El mismo XML visto en SQL Sentry Plan Explorer muestra la naturaleza anidada de las llamadas más claramente:
Salida posterior a la ejecución
SSMS muestra detalles solo para la consulta principal cuando se solicita la salida del plan posterior a la ejecución:
-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;
El impacto en el rendimiento de hacer lo contrario se puede mostrar usando la clase de evento Showplan XML Statistics Profile en SQL Server Profiler, usando una consulta que llama a la función varias veces (una vez por fila de entrada):
SELECT TOP (5)
p.ProductID,
dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;
Salida del perfilador:
Hay cinco planes separados posteriores a la ejecución para las ejecuciones de funciones, y uno para la consulta principal. Los cinco planes de funciones se ven así en el panel inferior del generador de perfiles:
El plan de consulta principal es:
La ejecución de la consulta sin la TOP (5)
cláusula da como resultado un plan de ejecución completo para cada una de las 504 filas de la tabla Producto. Probablemente pueda ver cómo esto rápidamente se saldría de control con tablas más grandes.
La situación de los desencadenantes se invierte. Estos no muestran ninguna información del plan previo a la ejecución, pero sí incluyen un plan posterior a la ejecución. Esto refleja la naturaleza basada en conjuntos de los desencadenantes; cada uno se dispara una vez para todas las filas afectadas, en lugar de una vez por fila.