¿NOLOCK siempre es malo?


34

Soy un desarrollador de informes que quiere que mis consultas sean lo más eficientes posible. Solía ​​trabajar con un DBA que me dijo, creo que porque siempre estaba lidiando con informes en un servidor de producción, para usar NOLOCKen cada consulta.

Ahora, trabajo con un DBA que ha prohibido NOLOCKbajo cualquier circunstancia, incluso cuando un informe mío (debido a una considerable falta de índices en un par de tablas) está deteniendo la replicación y las actualizaciones del sistema. En mi opinión, en este caso, a NOLOCKsería algo bueno.

Dado que la mayor parte de mi capacitación en SQL ha recibido varios DBA con opiniones muy diferentes, quería preguntar esto a una amplia variedad de DBA.


1
El otro lado de esta discusión: dba.stackexchange.com/q/2684/2660
Nick Chammas

Respuestas:


30

Si su informe bloquea actualizaciones de que su DBA es correcto: no debe usarlo NOLOCK. El mismo hecho de que no son conflictos es una clara indicación de que si quieres usar las lecturas sucias se podrían obtener informes incorrectos.

En mi opinión, siempre hay mejores alternativas que NOLOCK:

  • ¿Sus tablas de producción son de solo lectura y nunca se modifican? ¡Marque la base de datos de solo lectura!
  • Los escaneos de tablas causan conflictos de bloqueo? Indice las tablas adecuadamente, los beneficios son múltiples.
  • ¿No puede modificar / no sabe cómo indexar adecuadamente? Utilice la AISLAMIENTO INSTANTÁNEA .
  • ¿No se puede cambiar la aplicación para usar la instantánea? ¡Active la lectura de lectura confirmada !
  • ¿Ha medido el impacto del versionado de filas y tiene evidencia de que afecta el rendimiento? ¿No puedes indexar los datos? y estás de acuerdo con los informes incorrectos ? Luego, como mínimo, hágase un favor y use SET TRANSACTION ISOLATION LEVEL, no una sugerencia de consulta. Será más fácil arreglar más tarde el nivel de aislamiento en lugar de modificar cada consulta.

66
Tenga cuidado: activar la lectura de lectura confirmada puede romper algún código.
AK

33

No siempre es malo.

Por supuesto, le permite leer valores no confirmados (que pueden revertirse y, por lo tanto, nunca existieron lógicamente), así como permitir fenómenos como leer valores varias veces o nada.

Los únicos niveles de aislamiento que garantizan que no encontrará tales anomalías son serializables / instantáneas. Los valores de lectura repetibles pueden perderse si se mueve una fila (debido a una actualización de clave) antes de que la exploración llegue a esta fila, los valores confirmados de lectura se pueden leer dos veces si una actualización de clave hace que una fila de lectura anterior avance.

nolockSin embargo, es más probable que surjan estos problemas porque, de forma predeterminada, en este nivel de aislamiento utilizará una exploración ordenada por asignación cuando estima que hay más de 64 páginas para leer . Además de la categoría de problemas que surgen cuando las filas se mueven entre páginas debido a actualizaciones de claves de índice, estos escaneos ordenados por asignación también son vulnerables a problemas con divisiones de página (donde las filas pueden perderse si la página recién asignada es anterior en el archivo al punto ya escaneado o leído dos veces si una página ya escaneada se divide en una página posterior en el archivo).

Al menos para consultas simples (tabla única) es posible desalentar el uso de estos escaneos y obtener un escaneo ordenado por clave nolocksimplemente agregando un ORDER BY index_keya la consulta para que la Orderedpropiedad del IndexScanes true.

Pero si su aplicación de informes no necesita cifras absolutamente precisas y puede tolerar la mayor probabilidad de tales inconsistencias, podría ser aceptable.

Pero ciertamente no deberías tirarlo en todas las consultas con la esperanza de que sea un botón mágico "turbo". Además de la mayor probabilidad de encontrar resultados anómalos en ese nivel de aislamiento o ningún resultado en absoluto (error "No se pudo continuar la exploración con NOLOCK debido al movimiento de datos"), incluso hay casos en los que el rendimiento nolock puede ser mucho peor .


3
+1 - Lo usamos mucho porque nuestras tablas de producción nunca se modifican.
JNK

@JNK ¿Qué quieres decir con que nunca se modifica?
Kuberchaun

44
Martin, sugeriría palabras ligeramente diferentes: "bajo lectura, los valores comprometidos pueden perderse y leerse más de una vez". Podemos recuperar una fila más de dos veces en algunos casos exóticos.
AK

@ StarShip3000 Los datos que implementamos en producción son básicamente de solo lectura para los usuarios finales, por lo que la mayoría de sus vistas tienen pistas NOLOCK
JNK

11

¿Sus clientes toleran resultados inconsistentes en los informes? Si la respuesta es no, no debe usar NOLOCK: puede obtener resultados incorrectos bajo concurrencia. Escribí algunos ejemplos aquí , aquí y aquí . Estos ejemplos muestran resultados inconsistentes en READ COMMITTED y REPEATABLE READ, pero puede ajustarlos y obtener resultados incorrectos con NOLOCK también.


La mayoría de los informes que creo no se ejecutan con datos actuales. La mayoría de los clientes están ejecutando informes son datos de ayer. ¿Cambiaría su respuesta si ese fuera el caso?
DataGirl

8

La mayoría de los informes que creo no se ejecutan con datos actuales. La mayoría de los clientes están ejecutando informes son datos de ayer. ¿Cambiaría su respuesta si ese fuera el caso?

Si ese es el caso, entonces tiene una opción más posible: en
lugar de ejecutar sus consultas en la base de datos de producción y perder el tiempo con bloqueos NOLOCK, puede ejecutar sus informes desde una copia de la base de datos de producción.

Puede configurarlo para que se restaure automáticamente desde una copia de seguridad cada noche .
Aparentemente, sus informes se ejecutan en servidores en los sitios de los clientes, por lo que no sé si configurar esto sería una solución viable para usted.
(pero de nuevo ... deberían tener copias de seguridad de todos modos, por lo que todo lo que necesita es un poco de espacio en el servidor para restaurarlas)

Soy un desarrollador interno, así que esto es más fácil para mí porque tengo control total sobre los servidores y las bases de datos.

Puede hacer esto al menos para los informes que solo necesitan datos de ayer y anteriores. Tal vez algunos informes tengan que permanecer en la base de datos de producción, pero al menos mueve parte de la carga a otra base de datos (o mejor aún, a otro servidor).

También tengo la misma situación en el trabajo:
estamos utilizando una copia de la base de datos de producción como esta para casi todos los informes, pero hay algunas consultas que requieren los datos de hoy.


Me gusta su respuesta y funcionaría, si tuviera el control total, lo cual no tenía. Muchas veces, no tengo control total y no puedo crear índices. Tengo suerte si puedo ejecutar / mostrar planes de ejecución.
DataGirl
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.