Rendimiento de Inline-TVF vs. Vistas

9

Tengo una base de datos donde estoy usando TVF en línea (funciones de valor de tabla) en lugar de vistas. Por ejemplo, podría tener dos tablas llamadas [modelo de automóvil] y [fabricante de automóviles] que uniré dentro de TVF [fnCarBrands].

Luego, estos TVF son llamados por otros TVF para realizar más procesamiento e informes. Entonces podría tomar mi función [fnCarBrands] y unirme a la tabla [Año de compra] para formar una función [fnCarBrandHistory]. Y así sucesivamente para varias capas de TVF.

Probablemente podría obtener la misma funcionalidad usando vistas, ya que mis TVF en línea son realmente solo uniones de tablas y otros TVF.

¿Cómo se compara el rendimiento de los TVF en línea escritos de esta manera con las vistas?

Puño de la furia
fuente
Lo más probable es que vea los mismos planes de ejecución y el mismo rendimiento.
AK
eso es lo que pensé, pero me dijeron que el TVF actúa como un paréntesis en álgebra: obliga al motor DB a completar esa consulta primero antes de optimizar. Me dicen que el uso de vistas permite que el optimizador optimice toda la consulta como una unidad.
FistOfFury
Una especie de nota al margen, pero ¿alguna idea de por qué se usaron TVF en lugar de vistas? ¿Solo el enfoque de code-monkey vs data-monkey para el problema?
Mark Storey-Smith
@ MarkStorey-Smith sí, la razón es, como usted dice, el enfoque de mono de código vs mono de datos.
FistOfFury

Respuestas:

12

El optimizador de consultas trata una función con valores de tabla en línea exactamente como una vista:

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

Una función con valores de tabla de varias instrucciones se ejecuta más como un procedimiento almacenado. Por lo general, deben ejecutarse varias veces, en lugar de plegarse en la 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
fuente
1
@Andomar, entiendo que los TVF de varias instrucciones se ejecutan como un recuadro negro, el motor no sabe qué contiene y no puede optimizar la consulta. ¿Tiene algún artículo al que pueda hacer referencia que diga que las vistas y los TVF en línea son equivalentes?
FistOfFury
4

Deberá crear vistas similares a las funciones y consultar cada una mirando el plan de ejecución para ver qué sucede con cada una.

mrdenny
fuente
Exactamente. Evaluación comparativa, ver por sí mismo: esta es la única forma confiable de aprender.
AK
@mrdenny ¿No hay forma de predecir cómo tratará el optimizador cada tipo de consulta? Seguramente hay algunas reglas que sigue.
FistOfFury
2
@FistOfFury Sí, hay reglas, miles y miles de ellas, complementadas con cientos de años de código heurístico para desarrolladores. Es por eso que tendrá que probar o pedirle a Microsoft el código fuente del optimizador.
Mark Storey-Smith
Si desea comprender mejor cómo el motor de la base de datos determina qué hacer, entonces debe leer sobre SQL Server Internals, amazon.com/s/…
HLGEM
3

Por supuesto, crear vistas que llamen a otras vistas también es un asesino de rendimiento. No sigas por esa ruta. Escriba las consultas que necesita y no use TVF ni vistas si desea rendimiento. Es la estratificación la que está creando el problema, esto casi siempre es algo malo cuando se consulta una base de datos y puede terminar rápidamente alcanzando el límite de la cantidad de tablas a las que también puede hacer referencia, especialmente porque a menudo termina haciendo referencia al mismas tablas en diferentes capas. Además, si bien parece que sería más fácil de mantener, no lo es. Intente depurar o agregar una columna debido a un nuevo requisito cuando la capa que necesita arreglar esté en la parte inferior.

HLGEM
fuente