Efecto de la sugerencia NOLOCK en las instrucciones SELECT

199

Supongo que la verdadera pregunta es:

Si no me interesan las lecturas sucias, agregar la sugerencia with (NOLOCK) a una instrucción SELECT afectará el rendimiento de:

  1. la declaración SELECT actual
  2. otras transacciones contra la tabla dada

Ejemplo:

Select * 
from aTable with (NOLOCK)
Bob Probst
fuente
3
Estas respuestas SO y DBA son un poco más claras sobre lo que realmente está sucediendo.
Trisped

Respuestas:

289

1) , una selección con NOLOCKse completará más rápido que una selección normal.

2) , una selección con NOLOCKpermitirá que otras consultas contra la tabla afectada se completen más rápido que una selección normal.

¿Por qué sería esto?

NOLOCKgeneralmente (dependiendo de su motor de base de datos) significa darme sus datos, y no me importa en qué estado se encuentre, y no me moleste en mantenerlos quietos mientras lee. Es todo más rápido, menos intensivo en recursos y muy muy peligroso.

Se le debe advertir que nunca haga una actualización o realice algo crítico para el sistema, o donde se requiera una corrección absoluta utilizando datos que se originaron en una NOLOCKlectura. Es absolutamente posible que estos datos contengan filas que se eliminaron durante la ejecución de la consulta o que se hayan eliminado en otras sesiones que aún no se han finalizado. Es posible que estos datos incluyan filas que se hayan actualizado parcialmente. Es posible que estos datos contengan registros que violen las restricciones de clave externa. Es posible que estos datos excluyan filas que se han agregado a la tabla pero que aún no se han confirmado.

Realmente no tiene forma de saber cuál es el estado de los datos.

Si está tratando de obtener cosas como un Recuento de filas u otros datos de resumen donde un margen de error es aceptable, entonces NOLOCKes una buena manera de aumentar el rendimiento de estas consultas y evitar que afecten negativamente el rendimiento de la base de datos.

Siempre use la NOLOCKsugerencia con gran precaución y trate los datos que devuelva de forma sospechosa.

tom.dietrich
fuente
Gracias. Esto es lo que he estado asumiendo, pero un colega me preguntó al respecto y mi investigación inicial me hizo cuestionarme. ¡La documentación de SQLServer 2005 dice que con NOLOCK es el esquema de bloqueo predeterminado para todas las instrucciones select! Supongo que mis pistas serían redundantes en ...
Bob Probst
2
... 2005 y no tiene ningún efecto. Estamos ejecutando 2000 en este momento (gracias a nuestro proveedor) y no hay una declaración similar en la documentación.
Bob Probst
44
Tu amigo necesita leer la documentación. Sugerencia de tabla (Transact-SQL) msdn.microsoft.com/en-us/library/ms187373(SQL.90).aspx
Pittsburgh DBA
9
Nota al margen: si esto fuera cierto, sería un caos absoluto.
Pittsburgh DBA
1
Los puntos 1 y 2 deben restringirse a 1) "... cuando una acción de inserción / actualización / eliminación está pendiente en la tabla ". y 2) "... permitirá insertar / actualizar / eliminar consultas contra ...". Yo (preferencia personal) cambiaría las instancias de "más rápido" a "antes" ya que la diferencia está esperando que se complete otro proceso.
Trisped
61

NOLOCK hace que la mayoría de las instrucciones SELECT sean más rápidas debido a la falta de bloqueos compartidos. Además, la falta de emisión de los bloqueos significa que los escritores no se verán obstaculizados por su SELECT.

NOLOCK es funcionalmente equivalente a un nivel de aislamiento de READ UNCOMMITTED. La principal diferencia es que puede usar NOLOCK en algunas tablas pero no en otras, si lo desea. Si planea usar NOLOCK en todas las tablas en una consulta compleja, entonces usar SET TRANSACTION ISOLATION LEAD READ UNCOMMITTED es más fácil, porque no tiene que aplicar la sugerencia a cada tabla.

Aquí hay información sobre todos los niveles de aislamiento a su disposición, así como sugerencias de tabla.

ESTABLECER NIVEL DE AISLAMIENTO DE TRANSACCIÓN

Sugerencia de tabla (Transact-SQL)

Pittsburgh DBA
fuente
2
Estoy de acuerdo, pero no completamente; Es importante señalar que una sugerencia NO BLOQUEAR / LEER NO COMPROMETIDA en realidad no mejora la velocidad de la consulta, pero más aún hace que parezca más rápido porque no tiene que esperar a que se completen las consultas anteriores. Entonces, realmente, la consulta PARECE más rápido, en lugar de ES MÁS rápido (creo).
Möoz
1
@BorhanMooz Bueno, existe el ahorro de no tener que solicitar bloqueos al administrador de bloqueos. Incluso si no hay otras consultas esperando, esto tiene un costo y una sobrecarga de memoria.
Pittsburgh DBA
1
Estaba discutiendo esto con algunos de mis compañeros de trabajo. Según tengo entendido, una consulta que utiliza una sugerencia WITH (NOLOCK) todavía requiere que se obtenga un bloqueo de esquema compartido ( mssqltips.com/sqlservertip/2470/… ).
Möoz
1
Sí, pero no miles de bloqueos compartidos en páginas o extensiones. Un bloqueo de esquema es UNA cerradura, NO MIL. Si queremos ser pedantes, podemos continuar debatiendo esto, pero sí, habrá una cantidad mínima de bloqueo por encima. Los ahorros son significativos. Haga los cálculos sobre esto: msdn.microsoft.com/en-us/library/aa337559(v=sql.100).aspx
Pittsburgh DBA
6

Será más rápido porque no tiene que esperar las cerraduras

StingyJack
fuente
¿Cuanto más rápido? ¿Podría proporcionar algún número de mejoras de velocidad?
Eugeniu Torica
55
"Cuánto" depende de lo que esté haciendo específicamente con sus datos y de cuánto tiempo normalmente tiene que esperar para la adquisición de un bloqueo.
StingyJack
El único punto de referencia correcto es el que crea y ejecuta usted mismo. Lo que todos te dicen es tan bueno como "el cheque está en el correo". He demostrado que muchos mitos y suposiciones están equivocados muchas veces al ejecutar mis propios puntos de referencia.
TravisO
^ @TravisO - es completamente correcto. He hecho que NOLOCK se ejecute más lento algunas veces. No estoy completamente seguro de por qué, pero lo estoy usando cuando soluciono problemas y no quiero afectar negativamente (sobre) la producción
StingyJack
2
  • La respuesta es si la consulta se ejecuta varias veces a la vez, porque cada transacción no tendrá que esperar a que se completen las demás. Sin embargo, si la consulta se ejecuta una sola vez, la respuesta es No.

  • . Hay una probabilidad significativa de que el uso cuidadoso de WITH (NOLOCK) acelere su base de datos en general. Significa que otras transacciones no tendrán que esperar a que termine esta declaración SELECT, pero por otro lado, otras transacciones se ralentizarán ya que ahora comparten su tiempo de procesamiento con una nueva transacción.

Tenga cuidado de usar soloWITH (NOLOCK) en sentencias SELECT en tablas que tengan un índice agrupado.

WITH (NOLOCK) a menudo se explota como una forma mágica de acelerar las transacciones de lectura de la base de datos.

El conjunto de resultados puede contener filas que aún no se han confirmado, que a menudo se deshacen más tarde.

Si WITH (NOLOCK) se aplica a una tabla que tiene un índice no agrupado, otras transacciones pueden cambiar los índices de fila a medida que los datos de la fila se transmiten a la tabla de resultados. Esto significa que al conjunto de resultados pueden faltar filas o mostrar la misma fila varias veces.

READ COMMITTED agrega un problema adicional en el que los datos se corrompen dentro de una sola columna donde varios usuarios cambian la misma celda simultáneamente.

WonderWorker
fuente