2012-04-23 36 views
12

En SQL Server 2008 tengo una visión V sobre tablas A y B que se ve más o menos así¿cómo sabe SQL Server para bloquear objetos de vista?

create view V as 
    select * from A 
    union all 
    select * from B 

lectura de V hace que una consulta a tomar bloqueos compartidos de intención en las tablas base, sino que también tiene un bloqueo compartido de intención en el objeto de vista.

Está claro por qué necesitamos los bloqueos de IS en las tablas, y podemos ver que el bloqueo de IS en la vista impide la modificación simultánea de las tablas subyacentes a la vista. Esta bien.

El plan de consulta no contiene ninguna mención de la vista. Está completamente compilado, y el plan resultante en este caso es una concatenación simple de filas de las dos tablas base. De hecho, la única mención de la vista en el plan de consulta XML está en el texto de la declaración.

Si agrega una segunda vista U sobre las tablas, la lectura de V no causa ningún bloqueo en U. Esto descarta que el motor solo tome un bloqueo IS en todas las vistas sobre A y B.

¿Cómo sabe el motor de la base de datos bloquear la vista?

  • ¿El texto de la declaración se analiza de nuevo?
  • ¿Hay algún otro canal de información entre el planificador de consultas y la ejecución subyacente para pasar esta información?

Véase el corresponding question on dba.stackexchange para más detalles.

+0

Presumiblemente, se inicia bloqueando la vista para evitar cambios en el diseño de la vista mientras se está utilizando. – JamieSee

+0

@JamieSee, tomaría un bloqueo S od Sch-M, entonces. – usr

+1

El plan de ejecución se almacena en un formato binario. No todo lo que contiene está representado en el XML que se nos muestra. –

Respuesta

0

De forma predeterminada, las vistas se expanden, como una macro, en las consultas que hacen referencia a ellas.

Esto se puede desactivar, o variar si están materializados, etc., pero la expansión en línea macro es la norma. Esto significa que el bloqueo, etc., se comporta como si se hizo lo siguiente ...

SELECT 
    * 
FROM 
    blah 
INNER JOIN 
(
    yourViewCode 
) 
    AS aView 
    ON aView.id = blh.id 
+1

Pero ** no ** se comportó así. – usr

+2

Y esto podría ser una buena conveniencia para entender, pero las vistas se compilan cuando se crean. Si las tablas subyacentes cambian, las vistas no se cambiarán por defalt. En particular, debe evitar "seleccionar *" en una vista por este motivo. –

+0

@Dems Soy consciente de que la vista se expande así, y no estoy hablando de un comportamiento fuera de esta norma ni de vistas materializadas. En cualquier caso, como señala usr, ese no es el comportamiento que estoy preguntando. –

2

Si nos fijamos en la vista sys.dm_exec_query_optimizer_info, que devuelve detalles del optimizador de consultas de SQL Server, uno de los detalles devuelto es el siguiente campo:

vista de referencia - Número de veces que un punto de vista ha sido referenciados en una consulta.

Al parecer el número de veces que una visión se hace referencia alguna parte se realiza un seguimiento , posiblemente como parte del plan de ejecución ... mi suposición es que incluso si se amplía la vista, el plan de ejecución contiene todavía detalles de las vistas que se usaron en la consulta y emite los bloqueos apropiados IS con respecto a estas vistas a las que se hace referencia.

+1

Podría tener más sentido si hubiera una estructura de datos separada para estas dependencias para que no tenga que escanear toda la memoria caché del plan cuando se modifiquen los objetos dependientes. Sin embargo, no creo que este grado de internos esté documentado en ninguna parte. –

+0

@MartinSmith Creo que tienes razón ... al igual que tu comentario a la pregunta, estas dependencias podrían incluirse en el binario del plan de ejecución. Busqué por un tiempo, y este DMV fue la única referencia que pude encontrar que abordaba el tema de forma remota. –

+0

@MichaelFredrickson Sí, es un buen comienzo, gracias por encontrarlo. Realmente me gustaría saber si está documentado en cualquier lugar que este bloqueo en la vista se tome, y en particular, no lo consideraría como un detalle interno de la implementación. Todo lo contrario: los bloqueos tomados parecen ser una parte visible de la semántica de la lectura a través de la vista. –

3

Copia desde my answer on dba.stackexchange:

De Conor Cunningham, la fuente última de nada motor-o relacionados con el optimizador:

Hacemos un seguimiento de las cosas durante la compilación en tiempo de ejecución para comprobar. No analizamos cosas en la ejecución para este fin.

Nota: las partes internas de lo que hacemos de una versión a otra no son garantizados. Esto está debajo del área de superficie oficialmente compatible.

Mi creencia es que la versión binaria del plan de ejecución (no el que se puede leer y expuestos a nosotros a través de XML, que es sólo un subconjunto de la versión binaria) debe contener algo de puntero a la vista (s) referenciado en el texto de consulta original (y esto fue aludido arriba). Obviamente, no está analizando el texto de la consulta todo el tiempo. Conor implica todo lo anterior, pero tiene cuidado de no revelar ningún detalle sobre dónde o cómo se almacena, ya que esto podría cambiar de una versión a otra o incluso con un service pack o una actualización acumulativa. Probablemente tampoco quiera alentar ningún trabajo de detective. :-)

Cuestiones relacionadas