Published on

June 28, 2012

Comprendiendo la sugerencia NOLOCK en SQL Server

¿Alguna vez has oído hablar de la sugerencia NOLOCK en SQL Server? Es un tema que a menudo genera debates entre desarrolladores y administradores de bases de datos. Algunos afirman que el uso de la sugerencia NOLOCK puede mejorar el rendimiento, mientras que otros argumentan que reduce el bloqueo y los bloqueos muertos al no adquirir ningún bloqueo. En este artículo, exploraremos qué sucede cuando usamos la sugerencia NOLOCK en consultas y analizaremos los bloqueos adquiridos.

Comencemos por analizar una consulta sin la sugerencia NOLOCK:

SELECT * FROM Sales.SalesOrderHeader a CROSS JOIN Sales.SalesOrderHeader b

Cuando analizamos los bloqueos adquiridos por esta consulta, podemos ver un bloqueo compartido a nivel de base de datos. Este bloqueo no está relacionado con la sugerencia NOLOCK y se adquiere al abrir una conexión a la base de datos para asegurarse de que otras sesiones no eliminen la base de datos mientras está en uso.

A continuación, podemos ver un bloqueo compartido de intención (IS) a nivel de tabla. Un bloqueo de intención indica que SQL Server tiene la intención de adquirir un bloqueo compartido (S) o un bloqueo exclusivo (X) en recursos más bajos en la jerarquía. En este caso, el bloqueo IS evita que otra transacción adquiera un bloqueo exclusivo (X) en la tabla, asegurando que la tabla no se modifique mientras se ejecuta la instrucción SELECT.

Finalmente, podemos ver un bloqueo compartido a nivel de página. Este bloqueo asegura que los datos en la página no se modifiquen mientras se están leyendo.

Ahora, veamos cómo funciona la sugerencia NOLOCK en conjunto con una instrucción de actualización:

BEGIN TRAN
UPDATE Sales.SalesOrderHeader SET status = 5 WHERE SalesOrderID = 43659

Si ejecutamos la instrucción SELECT y el script de análisis de bloqueo nuevamente, podemos ver que la solicitud de un bloqueo compartido en la página está en estado de espera. Esto se debe a que entra en conflicto con el bloqueo exclusivo de intención adquirido por la sesión de actualización en la página. Si bien esto ayuda a SQL Server a evitar lecturas sucias, también causa bloqueos. En este caso, la instrucción SELECT está bloqueada por la instrucción de actualización.

Ahora, intentemos la misma instrucción SELECT con la sugerencia NOLOCK:

SELECT * FROM Sales.SalesOrderHeader a WITH (NOLOCK) CROSS JOIN Sales.SalesOrderHeader b WITH (NOLOCK)

En este caso, podemos ver que solo se adquiere un bloqueo de esquema compartido en la tabla. No se realiza un bloqueo compartido en la página, lo que lleva a una lectura sucia. El bloqueo de esquema compartido a nivel de tabla es importante para asegurarse de que el esquema de la tabla no se modifique mientras se lee los datos.

Incluso si ejecutamos la instrucción SELECT después de la instrucción de actualización, se ejecutará sin bloqueos porque no está intentando adquirir bloqueos compartidos en las páginas. Sin embargo, esto también significa que realizará una lectura sucia.

El nivel de aislamiento READ UNCOMMITTED funciona de manera similar a la sugerencia NOLOCK. En lugar de especificar la sugerencia para cada tabla, puedes establecer el nivel de aislamiento en READ UNCOMMITTED.

Es importante tener en cuenta que si bien la sugerencia NOLOCK puede mejorar ligeramente el rendimiento al adquirir menos bloqueos en comparación con las declaraciones sin la sugerencia, también realiza lecturas sucias y puede producir resultados no deseados. Por lo tanto, es crucial usar la sugerencia NOLOCK con precaución.

Si encontraste útil esta publicación, asegúrate de darle me gusta a mi página en Facebook en http://www.facebook.com/practicalSqlDba y visitar mi sitio web en www.PracticalSqlDba.com.

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.