¿Se optimizan las vistas cuando les agrego una cláusula WHERE?

28

¿Hay alguna diferencia si filtra una vista dentro o fuera de la vista?

Por ejemplo, ¿hay alguna diferencia entre estas dos consultas?

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

O

SELECT Id
FROM MyView
WHERE SomeColumn = 1

Y MyViewse define como

SELECT Id, SomeColumn
FROM MyTable

¿Y la respuesta es diferente si la tabla de origen se encuentra en un servidor vinculado?

Lo pregunto porque tengo que consultar una tabla grande (44mil filas) dos veces desde un servidor vinculado y obtener un agregado de los resultados. Quiero saber si debo crear dos vistas para acceder a los datos, una para cada consulta, o si puedo salir con una sola vista y una WHEREcláusula.

Rachel
fuente
1
¿Por qué usarías una vista si solo tienes una tabla?
HLGEM
3
Seguridad @HLGEM?
JNK
2
@HLGEM La Vista en realidad contiene múltiples consultas a múltiples bases de datos en diferentes servidores, y las une a todas por un UNION ALL. Es mucho más fácil usar una Vista que tener que reescribir la consulta UNION cada vez que necesito los datos.
Rachel
1
@datagod Lo tendré en cuenta, gracias :) En este caso, hay una aplicación bastante pequeña que recopila datos de un montón de servidores, ejecuta algunos cálculos y emite un montón de informes. Tiene su propia base de datos porque algunos de los cálculos son bastante intensivos en recursos, y quería separarlo de todo lo demás.
Rachel

Respuestas:

12

No debería ver absolutamente ninguna diferencia en los planes o el rendimiento entre estas dos opciones. Cuando se consulta la vista, se expande a una consulta en la tabla base, lo que significa que se utilizará la misma búsqueda o exploración.

Ahora, dependiendo del tipo de datos y la selectividad de MyColumn, si desea crear un índice filtrado en la tabla base (cuando se muda a SQL Server 2008+), podría obtener un mejor rendimiento, pero esto nuevamente no será diferente a través de la vista o sin.

Aaron Bertrand
fuente
3
¿Qué pasa con esta pregunta , que pregunta por qué una consulta con la wherecláusula fuera de la vista tarda mucho más que cuando se coloca en la vista?
Rachel
1
Si las vistas no son para el rendimiento, ¿son solo para la estructura?
profimedica
1
Las vistas indexadas de @profimedica se pueden crear por razones de rendimiento (por ejemplo, para almacenar resultados intermedios como agregados en lugar de calcularlos en tiempo de ejecución). Si una vista no se materializa, puede ser por una variedad de razones: DRY (unión común o filtro realizado en muchas consultas diferentes), seguridad, ofuscación, simplificación de esquema.
Aaron Bertrand
5

Aquí hay un ejemplo rápido que muestra que no debería haber diferencia. La base de datos es la AdventureWorksbase de datos.

Dos definiciones de vista:

create view Person.vContactWhere
as

    select *
    from person.Contact
    where ContactID = 24

go

create view Person.vContactNoWhere
as

    select *
    from person.Contact

go

Aquí sería la primera consulta, con la WHEREcláusula incluida en la definición de la vista:

select *
from person.vContactWhere

Aquí está el plan de ejecución:

ingrese la descripción de la imagen aquí

Y la segunda consulta, con la WHEREcláusula no en la definición de la vista, sino en la SELECTconsulta:

select *
from person.vContactNoWhere
where ContactID = 24

Aquí está ese plan de ejecución:

ingrese la descripción de la imagen aquí

Como puede ver en estos planes de ejecución, son idénticos con resultados idénticos. No sé de una situación en la que este tipo de lógica / diseño arrojaría resultados diferentes. Por lo tanto, estaría dispuesto a decir que está a salvo de cualquier manera, e ir con preferencia personal (o procedimientos de compra).

Thomas Stringer
fuente
1
¿Qué pasa con esta pregunta , que pregunta por qué una consulta con la wherecláusula fuera de la vista tarda mucho más que cuando se coloca en la vista?
Rachel
1
@ Rachel Creo que gbn lo explicó bastante bien en su publicación y en el artículo que señaló. No sé cómo decirlo.
Thomas Stringer
Lo relacioné porque en ese caso, los planes de ejecución no eran los mismos, lo cual es diferente de lo que dice su respuesta.
Rachel
1
@Rachel El problema en ese ejemplo es una regla de transformación que falta . No solo se aplica a las vistas, sino también a los CTE y otras expresiones de tabla. En el caso general, no es válido insertar el predicado en expresiones de tabla que contengan funciones de clasificación, ya que eso cambiará el resultado. La razón por la que es válida en este caso es porque la Wherecláusula se ajusta a PARTITION BY. SQL Server 2008 parece tener una nueva regla SelOnSeqPrjpara reconocer este caso particular.
Martin Smith
1
@ Rachel - Más información sobre este tema aquí
Martin Smith
2

Basado en lo que estoy leyendo , SQL utilizará una vista estándar como una subconsulta al determinar el plan de ejecución.

Entonces, usando mi consulta de ejemplo,

SELECT Id
FROM MyView
WHERE SomeColumn = 1

donde MyViewse define como

SELECT Id, SomeColumn
FROM MyTable

debería generar el mismo plan de ejecución que

SELECT Id
FROM 
(
    SELECT Id, SomeColumn
    FROM MyTable
) as T
WHERE SomeColumn = 1

pero este plan de ejecución puede ser diferente de lo que se generaría con

SELECT Id
FROM MyTable
WHERE SomeColumn = 1

No estoy seguro de si esta respuesta sería la misma para las vistas indexadas

Rachel
fuente
No creo que sea un reemplazo de texto explícito como ese.
Aaron Bertrand
@AaronBertrand Puede que tengas razón. Sinceramente, no tengo idea ... Estoy aprendiendo sobre la marcha :) Esa suposición se basó en otras cosas que he estado leyendo sobre cómo las vistas son como macros. Edité la pregunta ligeramente para especificar que me estoy refiriendo a vistas estándar, no vistas indizadas.
Rachel
@Rachel: la sustitución ocurre con el árbol algebrizado que no está en un nivel textual.
Martin Smith
@MartinSmith Hrrmm, ¿no es eso lo que dije? ¿Que los planes de ejecución deberían ser los mismos, no que el texto sería el mismo? No estoy seguro de entender el "árbol algebrizado"
Rachel
Fue solo en respuesta a su comentario sobre la propia Q que dice que "inserta el texto de una Vista en su consulta" y el comentario de Aaron anterior. Alguna información sobre las etapas de análisis / compilación aquí . En realidad, su respuesta también menciona la sustitución de texto. Si esta es una distinción que vale la pena hacer. ¡No es seguro! Pero supongo que explica por qué sp_refreshviewes necesario lo que no haría el concepto de sustitución de texto.
Martin Smith