SQL Server NOLOCK y se une


153

Antecedentes: tengo una consulta de rendimiento crítico que me gustaría ejecutar y no me importan las lecturas sucias.

Mi pregunta es; Si estoy usando combinaciones, ¿tengo que especificar también la sugerencia de NOLOCK?

Por ejemplo; es:

SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b WITH (NOLOCK) ON a.ID = b.ID

Equivalente a:

SELECT * FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b ON a.ID = b.ID

¿O tendré que especificar la (NOLOCK)sugerencia en la unión para asegurarme de que no estoy bloqueando la tabla unida?

Respuestas:


166

No abordaré el READ UNCOMMITTEDargumento, solo su pregunta original.

Sí, necesitas WITH(NOLOCK)en cada tabla de la unión. No, tus consultas no son las mismas.

Prueba este ejercicio. Comience una transacción e inserte una fila en table1 y table2. No confirme ni revierta la transacción todavía. En este punto, su primera consulta volverá con éxito e incluirá las filas no confirmadas; su segunda consulta no regresará porque table2 no tiene la WITH(NOLOCK)pista.


18

Estaba bastante seguro de que necesita especificar el NOLOCKpara cada uno JOINen la consulta. Pero mi experiencia se limitó a SQL Server 2005.

Cuando busqué MSDN solo para confirmar, no pude encontrar nada definitivo. Las siguientes declaraciones parecen hacerme pensar que para 2008, sus dos declaraciones anteriores son equivalentes, aunque para 2005 no es el caso:

[SQL Server 2008 R2]

Todas las sugerencias de bloqueo se propagan a todas las tablas y vistas a las que accede el plan de consulta , incluidas las tablas y vistas a las que se hace referencia en una vista. Además, SQL Server realiza las comprobaciones de consistencia de bloqueo correspondientes.

[SQL Server 2005]

En SQL Server 2005, todas las sugerencias de bloqueo se propagan a todas las tablas y vistas a las que se hace referencia en una vista. Además, SQL Server realiza las comprobaciones de consistencia de bloqueo correspondientes.

Además, tenga en cuenta que esto se aplica tanto a 2005 como a 2008:

Las sugerencias de la tabla se ignoran si el plan de consulta no accede a la tabla. Esto puede ser causado por el optimizador que elige no acceder a la tabla, o porque se accede a una vista indexada. En el último caso, se puede evitar el acceso a una vista indizada mediante el uso de la OPTION (EXPAND VIEWS)sugerencia de consulta.


@In Sane: Interesante ... gracias por eso ... ¿Asumo que no estoy haciendo daño al incluirlo en las UNIONES, incluso si no es del todo necesario? La documentación sobre NOLOCK es bastante escasa como has mencionado; Tuve problemas para encontrar algo concluyente yo mismo.
DanP

2
@InSane: ¿De dónde sacaste esta información? Parece ir en contra de la respuesta aceptada.
Jay Sullivan

1
@notfed - consulte el enlace de technet technet.microsoft.com/en-us/library/ms187373(v=sql.105).aspx - puede cambiar la versión de la base de datos en la parte superior para comparar el mismo artículo para diferentes versiones de la base de datos
Jagmag

2
El texto de 2005 habla de VIEWS. Entonces, si lo hace "desde myview con (nolock)", entonces dice que el nolock se propaga a todas las tablas y vistas involucradas en myview (podría tener 10 uniones allí). No estoy seguro de lo que significa exactamente el texto de 2008, ya que agrega "accedido por el plan de consulta" además de las vistas.
Thierry_S

9

Ninguno. Establece el nivel de aislamiento en el READ UNCOMMITTEDque siempre es mejor que dar pistas de bloqueo individuales. O, mejor aún, si le preocupan detalles como la consistencia , use el aislamiento de instantáneas .


@Remus: No estoy seguro de poder usar READ UNCOMMITTED en mi caso porque estoy accediendo a la conexión a través de NHibernate para realizar una llamada ADO.NET sin procesar especial; ¿se puede especificar esto en línea en la consulta o obedecerá el nivel de transacción presente en la transacción de NHibernate?
DanP

Envuelva la llamada using (TransactionScope scope=new TransactionScope(..., TransactionOptions) {...}y configure las IsolationLevelopciones en: msdn.microsoft.com/en-us/library/…
Remus Rusanu

@Remus: Desafortunadamente, la gestión de transacciones se realiza en un nivel mucho más alto que esto, por lo que tampoco es una opción.
DanP

Veo. Luego, para responder a su pregunta: NOLOCK es una sugerencia de tabla y, como tal, se aplica al conjunto de filas al que se agrega (tabla, vista, TVF, etc.). Si tiene varios conjuntos de filas unidos en una consulta, cada uno necesitaría su propia sugerencia NOLOCK.
Remus Rusanu

2
¿Pero ha considerado el aislamiento de instantáneas? ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT ON;. Los resultados son espectaculares, ya que todas las lecturas comprometidas de lectura normal se convierten en lecturas instantáneas, sin bloqueo pero consistentes. El costo es mayor tempdbcarga: msdn.microsoft.com/en-us/library/ms175492.aspx
Remus Rusanu
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.