2010-09-29 9 views
6

Tengo una vista compleja que utilizo para extraer una lista de claves primarias que indican filas en una tabla que se han modificado entre dos puntos temporales.Unirme a vistas en SQLServer con el comportamiento extraño del optimizador de consultas

Esta vista tiene que consultar 13 tablas relacionadas y mirar una tabla de registro de cambios para determinar si una entidad está "sucia" o no.

Aún con todo esto en marcha, haciendo una consulta sencilla:

select * from vwDirtyEntities; 

Toma sólo 2 segundos.

Sin embargo, si la cambio a

select 
    e.Name 
from 
    Entities e 
     inner join vwDirtyEntities de 
      on e.Entity_ID = de.Entity_ID 

Esto toma 1,5 minutos.

Sin embargo, si hago esto:

declare @dirtyEntities table 
(
    Entity_id uniqueidentifier; 
) 

insert into @dirtyEntities 
    select * from vwDirtyEntities; 


select 
    e.Name 
from 
    Entities e 
     inner join @dirtyEntities de 
      on e.Entity_ID = de.Entity_ID 

consigo los mismos resultados en sólo 2 segundos.

Esto me lleva a creer que SQLServer está evaluando la vista por fila cuando se unió a Entidades, en lugar de construir un plan de consulta que implique unir la unión interna individual anterior a las otras uniones en la vista.

Tenga en cuenta que quiero unirme al conjunto de resultados completo de esta vista, ya que filtra solo las claves que deseo internamente.

Sé que podría convertirlo en una vista materializada, pero esto implicaría un esquema que vincule la vista y sus dependencias y no me gusta la sobrecarga que mantendría el índice (Esta vista solo se consulta para las exportaciones, mientras que hay muchas más escrituras en las tablas subyacentes).

Entonces, además de usar una variable de tabla para almacenar en caché los resultados de la vista, ¿hay alguna forma de decirle a SQL Server que guarde en caché la vista mientras evalúa la unión? Traté de cambiar el orden de unión (Seleccionar de la vista y unirme contra Entidades), sin embargo eso no hizo ninguna diferencia.

La vista en sí también es muy eficiente, y no hay espacio para optimizar allí.

Respuesta

5

No hay nada de mágico en una vista. Es una macro que se expande. El optimizador decide cuándo JOINed para expandir la vista a la consulta principal.

Voy a abordar otros puntos de su mensaje:

  • que ha descartado una vista indizada. Una vista solo puede ser una entidad discreta cuando está indexada

  • SQL Server nunca hará una consulta RBAR por sí mismo. Solo los desarrolladores pueden escribir bucles.

  • no existe el concepto de almacenamiento en caché: cada consulta utiliza datos más recientes a menos que utilice tablas temporales

  • insiste en usar el punto de vista que usted ha decidido es muy eficiente.Pero no tienen idea de cómo son tratados vistas por el optimizador y tiene tablas

  • SQL es declarativa: orden de combinación por lo general no importa

  • Muchos desarrollador serio DB no utilice puntos de vista debido a las limitaciones de esta manera: no son reutilizables porque son macros

Editar, otra posibilidad. Predicate pushing en SQL Server 2005. Es decir, SQL Server no puede insertar la condición JOIN "más profundamente" en la vista.

+0

Si miras el historial de edición de publicaciones de Omg Ponies, verás que respondí con un simple comentario (aún está allí), y se desquició. Por contexto, aquí está su respuesta original: http://stackoverflow.com/revisions/2be5678d-7d09-4c14-9043-c4769f9f9c03/view-source. – FlySwat

+0

Y aquí está la edición que hizo después de mi comentario: http://stackoverflow.com/revisions/0d5a1cb1-1f89-4fba-96f4-c270d0543805/view-source. Nunca lo ataqué, comenzó a lanzarse. – FlySwat

+0

En lo que respecta al orden de unión, no importa. Eso puede ser cierto en teoría, pero en la práctica he visto volver a ordenar explícitamente las uniones para ser beneficiosas, generalmente porque permite a la base de datos descartar conjuntos de datos más grandes que no coincidirán antes de evaluar otras uniones. – FlySwat

Cuestiones relacionadas