with update readpast inner index sql-server nolock

sql-server - update - with nolock sql server inner join



¿Qué es "con(nolock)" en SQL Server? (16)

Desafortunadamente no se trata solo de leer datos no comprometidos. En el fondo, puede terminar leyendo las páginas dos veces (en el caso de una división de páginas), o puede perder las páginas por completo. Por lo tanto, sus resultados pueden ser muy sesgados.

Echa un vistazo a el artículo de Itzik Ben-Gan . Aquí hay un extracto:

"Con la sugerencia NOLOCK (o establecer el nivel de aislamiento de la sesión en LEER NO COMPROMETIDO) le dice a SQL Server que no espera consistencia, por lo que no hay garantías. Tenga en cuenta que" datos inconsistentes "no solo significa que es posible que vea cambios no confirmados que luego se retrotrajaron, o cambios de datos en un estado intermedio de la transacción. También significa que en una consulta simple que analiza todos los datos de tabla / índice SQL Server puede perder la posición de análisis, o puede terminar conseguir la misma fila dos veces ".

¿Alguien puede explicar las implicaciones de usar with (nolock) en las consultas, cuando debería / no debería usarlo?

Por ejemplo, si tiene una aplicación bancaria con altas tasas de transacción y una gran cantidad de datos en ciertas tablas, ¿en qué tipo de consultas no estaría bien? ¿Hay casos en los que siempre debe usarlo o nunca usarlo?


El ejemplo de libro de texto para el uso legítimo de la sugerencia nolock es el muestreo de informes en una base de datos OLTP de alta actualización.

Para tomar un ejemplo tópico. Si un gran banco de la calle principal de EE. UU. Quisiera publicar un informe por hora en busca de los primeros indicios de una ejecución a nivel de ciudad en el banco, una consulta nolock podría escanear tablas de transacciones que suman depósitos en efectivo y retiros de efectivo por ciudad. Para un informe de este tipo, el pequeño porcentaje de error causado por las transacciones de actualización anuladas no reduciría el valor del informe.


He usado para recuperar un "siguiente lote" para cosas que hacer. No importa en este caso cuál es el elemento exacto, y tengo muchos usuarios ejecutando esta misma consulta.


La pregunta es qué es peor:

  • un punto muerto, o
  • un valor incorrecto?

Para las bases de datos financieras, los puntos muertos son mucho peores que los valores erróneos. Sé que suena al revés, pero escúchame. El ejemplo tradicional de transacciones de base de datos es actualizar dos filas, restando de una y agregando a otra. Eso está mal.

En una base de datos financiera se utilizan transacciones comerciales. Eso significa agregar una fila a cada cuenta. Es de suma importancia que estas transacciones se completen y que las filas se escriban con éxito.

Conseguir que el saldo de la cuenta sea incorrecto temporalmente no es un gran problema, para eso está la reconciliación al final del día. Y es mucho más probable que ocurra un sobregiro de una cuenta porque se están usando dos cajeros automáticos a la vez que debido a una lectura no confirmada de una base de datos.

Dicho esto, SQL Server 2005 solucionó la mayoría de los errores que hicieron que NOLOCK necesario. Entonces, a menos que esté utilizando SQL Server 2000 o anterior, no debería necesitarlo.

Otras lecturas
Versiones de nivel de fila


La respuesta más simple es una pregunta simple: ¿necesita que sus resultados sean repetibles? En caso afirmativo, NOLOCKS no es apropiado bajo ninguna circunstancia.

Si no necesita repetibilidad, nolocks puede ser útil, especialmente si no tiene control sobre todos los procesos que se conectan a la base de datos de destino.


Mis 2 centavos: tiene sentido usar WITH (NOLOCK ) cuando necesite generar informes. En este punto, los datos no cambiarían mucho y no querría bloquear esos registros.


No está seguro de por qué no está envolviendo transacciones financieras en transacciones de base de datos (como cuando transfiere fondos de una cuenta a otra, no confirma un lado de la transacción a la vez, por eso existen transacciones explícitas). Incluso si su código está relacionado con las transacciones comerciales, como parece, todas las bases de datos transaccionales tienen el potencial de realizar reversiones implícitas en caso de errores o fallas. Creo que esta discusión está muy por encima de tu cabeza.

Si tiene problemas de bloqueo, implemente el control de versiones y limpie su código.

Ningún bloqueo no solo devuelve valores erróneos, sino también registros fantasmas y duplicados.

Es un error común pensar que siempre hace que las consultas se ejecuten más rápido. Si no hay bloqueos de escritura en una tabla, no hay ninguna diferencia. Si hay bloqueos en la tabla, puede hacer que la consulta sea más rápida, pero hay una razón por la que se inventaron los bloqueos en primer lugar.

Para ser justos, aquí hay dos escenarios especiales donde una sugerencia nolock puede proporcionar utilidad

1) La base de datos del servidor SQL anterior a 2005 que necesita ejecutar una consulta larga contra la base de datos OLTP en vivo, puede ser la única manera.

2) La aplicación mal escrita que bloquea los registros y devuelve el control a la interfaz de usuario y los lectores se bloquean indefinidamente. Nolock puede ser útil aquí si la aplicación no se puede arreglar (un tercero, etc.) y la base de datos es anterior a 2005 o la versión no se puede activar.


Otro caso en el que generalmente está bien es en una base de datos de informes, donde los datos tal vez ya están envejecidos y las escrituras simplemente no ocurren. Sin embargo, en este caso, el administrador debe establecer la opción en el nivel de la base de datos o de la tabla al cambiar el nivel de aislamiento predeterminado.

En el caso general: puede usarlo cuando esté seguro de que está bien leer datos antiguos. Lo importante a recordar es que es muy fácil equivocarse . Por ejemplo, incluso si está bien en el momento de escribir la consulta, ¿está seguro de que algo no cambiará en la base de datos en el futuro para que estas actualizaciones sean más importantes?

También voy a la segunda idea de que probablemente no sea una buena idea en la aplicación de banca. O aplicación de inventario. O en cualquier lugar que estés pensando en transacciones.


Puede usarlo cuando solo está leyendo datos, y realmente no le importa si está obteniendo datos que aún no están confirmados.

Puede ser más rápido en una operación de lectura, pero realmente no puedo decir cuánto.

En general, recomiendo no usarlo, ya que leer datos no confirmados puede ser un poco confuso.


Respuesta simple: siempre que su SQL no esté modificando los datos y tenga una consulta que pueda interferir con otra actividad (a través del bloqueo).

Vale la pena considerar las consultas utilizadas para los informes, especialmente si la consulta lleva más de, por ejemplo, 1 segundo.

Es especialmente útil si tiene informes de tipo OLAP que está ejecutando contra una base de datos OLTP.

La primera pregunta, sin embargo, es "¿por qué me preocupo por esto?" En mi experiencia, el comportamiento de bloqueo predeterminado a menudo tiene lugar cuando alguien está en el modo "intentar cualquier cosa" y este es un caso en el que las consecuencias inesperadas no son improbables. Muy a menudo es un caso de optimización prematura y puede dejarse incrustado fácilmente en una aplicación "por si acaso". Es importante entender por qué lo está haciendo, qué problema resuelve y si realmente tiene el problema.


Si está manejando transacciones financieras, entonces nunca querrá usar nolock . nolock se utiliza mejor para seleccionar tablas grandes que tienen muchas actualizaciones y no le importa si el registro que obtiene podría estar desactualizado.

Para los registros financieros (y casi todos los demás registros en la mayoría de las aplicaciones) nolock causaría estragos, ya que potencialmente podría leer los datos de un registro que se estaba escribiendo y no obtener los datos correctos.


Use nolock cuando esté de acuerdo con los datos "sucios". Lo que significa que nolock también puede leer datos que están en proceso de ser modificados y / o datos no confirmados.

Por lo general, no es una buena idea usarlo en un entorno de alta transacción y es por eso que no es una opción predeterminada en la consulta.


WITH (NOLOCK) es el equivalente a usar READ UNCOMMITED como nivel de aislamiento de transacción. Por lo tanto, corre el riesgo de leer una fila no confirmada que posteriormente se retrotrae, es decir, datos que nunca llegaron a la base de datos. Por lo tanto, aunque puede evitar que las lecturas se bloqueen en otras operaciones, conlleva un riesgo. En una aplicación de banca con altas tasas de transacciones, probablemente no sea la solución correcta para cualquier problema que esté tratando de resolver con IMHO.


Yo uso con (nolock) sugerencia particularmente en bases de datos SQLServer 2000 con alta actividad. Sin embargo, no estoy seguro de que sea necesario en SQL Server 2005. Recientemente agregué esa sugerencia en un SQL Server 2000 a solicitud del DBA del cliente, porque estaba notando muchos bloqueos de registros SPID.

Todo lo que puedo decir es que el uso de la sugerencia NO nos ha afectado y parece haber resuelto el problema del bloqueo. El DBA de ese cliente en particular básicamente insistió en que usáramos la sugerencia.

Por cierto, las bases de datos con las que trato son back-ends de los sistemas de reclamos médicos empresariales, por lo que estamos hablando de millones de registros y más de 20 tablas en muchas combinaciones. Normalmente agrego una sugerencia WITH (nolock) para cada tabla en la combinación (a menos que sea una tabla derivada, en cuyo caso no puede usar esa sugerencia en particular)


NOLOCK es equivalente a READ UNCOMMITTED , sin embargo, Microsoft dice que no debe usarlo para las declaraciones UPDATE o DELETE :

Para las declaraciones de ACTUALIZACIÓN o BORRAR: Esta característica se eliminará en una versión futura de Microsoft SQL Server. Evite usar esta función en nuevos trabajos de desarrollo y planee modificar las aplicaciones que actualmente usan esta función.

http://msdn.microsoft.com/en-us/library/ms187373.aspx

Este artículo se aplica a SQL Server 2005, por lo que el soporte para NOLOCK existe si está usando esa versión. Con el fin de proteger su código en el futuro (suponiendo que haya decidido utilizar lecturas sucias), podría usar esto en sus procedimientos almacenados:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED


Respuesta corta:

Nunca utilice WITH (NOLOCK) .

Respuesta larga:

NOLOCK se utiliza a menudo como una forma mágica de acelerar las lecturas de la base de datos, pero trato de evitar usarlo siempre que sea posible.

El conjunto de resultados puede contener filas que aún no se han confirmado, que a menudo se retrotraen posteriormente.

Un error o conjunto de resultados puede estar vacío, pueden faltar filas o mostrar la misma fila varias veces.

Esto se debe a que otras transacciones están moviendo datos al mismo tiempo que lo estás leyendo.

LEER COMPROMETIDO agrega un problema adicional donde los datos se corrompen dentro de una sola columna donde varios usuarios cambian la misma celda simultáneamente.

También hay otros efectos secundarios, que resultan en el sacrificio del aumento de velocidad que esperabas ganar en primer lugar.

Se puede argumentar que está bien usarlo en lugares donde pueda salirse con la suya, pero ¿cuál es el punto? No puedo pensar en ninguna situación en la que los datos dañados sean aceptables.

Nunca uses NOLOCK nunca.

(siempre)