sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo evitar los interbloqueos de SQL con el ajuste de consultas:consejos de Brent Ozar

Como parte de la serie de otoño de los días de capacitación en bases de datos de Quest, Brent Ozar, maestro certificado de Microsoft, presentó un tutorial sobre "Evitar interbloqueos con Query Tuning". El programa se centró en los tres problemas de simultaneidad que ocurren en SQL Server, tres formas de solucionarlos y una forma que parece solucionarlos, pero en realidad no lo hace.

Problemas de concurrencia:Bloqueos, bloqueos e interbloqueos en SQL Server

¿Qué son los problemas de concurrencia? Ocurren cuando las consultas intentan evitar conflictos entre sí sobre objetos de base de datos como tablas. Ellos son:

  • Bloqueo – Las consultas hacen esto todo el tiempo para evitar que otras consultas usen una tabla al mismo tiempo. Esta es una operación normal de la base de datos.
  • Bloqueo  – Esto ocurre cuando una consulta tiene un bloqueo normal, pero otra consulta intenta adquirir el mismo bloqueo. La segunda consulta tiene que esperar tanto tiempo como sea necesario para que la primera consulta libere el bloqueo. Dependiendo de la naturaleza de la primera consulta, la segunda podría estar esperando un tiempo muy corto o muy largo. Son esas largas esperas las que realmente afectan el rendimiento.
  • Bloqueo – Los interbloqueos ocurren cuando una consulta toma un bloqueo, otra consulta toma un bloqueo diferente y luego cada una quiere adquirir el bloqueo del otro. SQL Server resuelve esto al designar una de las consultas como la víctima y matarla para romper el enfrentamiento. Aunque una de las consultas puede continuar, esto también tiene un impacto en el rendimiento.

Solucionar problemas de simultaneidad

Independientemente de si experimenta bloqueos o interbloqueos en SQL Server, hay formas de solucionar los problemas de simultaneidad. Brent presentó estos tres métodos y pasó la mayor parte del resto de la sesión centrándose en el segundo:corregir el código incorrecto.

  1. Tenga suficientes índices para que sus consultas sean rápidas, pero no tantos como para ralentizar las cosas al hacer que las consultas mantengan más bloqueos durante más tiempo
  2. Ajuste su código transaccional para que las consultas funcionen a través de tablas en el mismo orden predecible cada vez
  3. Utilice el nivel de aislamiento adecuado para las necesidades de su aplicación

Mientras saltaba a la parte práctica del programa, Brent comentó sobre el uso de sentencias NOLOCK para bloqueo y punto muerto. Advirtió que NOLOCK realmente no soluciona estos problemas porque se basa en "lecturas sucias"; esencialmente, ignora los bloqueos de fila de otras consultas.

En su demostración de esto utilizando la base de datos Stack Overflow, creó una consulta simple que buscaba y contaba a las personas llamadas "Alex". Luego, creó otra consulta que ejecutaría una actualización sobre las personas que no llamado Alex, sin inserciones ni eliminaciones de registros. Una consulta no debe tener nada que ver con la otra. Pero, ejecutarlos juntos conduce a diferentes resultados en la cantidad de personas llamadas Alex. Esto se debe a que NOLOCK le permite ver datos que no se confirmaron, lo que genera resultados aleatorios que no puede predecir. Solo ocurre bajo concurrencia.

Claramente, se necesita una solución mejor para el bloqueo y el interbloqueo en SQL Server que no conduzca a resultados aleatorios e impredecibles.

Una mejor solución para los puntos muertos de SQL

Luego, Brent demostró cómo solucionar un interbloqueo cambiando el código que lo causa. Su primera demostración mostró una situación simple que involucraba dos mesas para que la audiencia pudiera ver un punto muerto en cámara lenta mientras sucedía. Dado que SQL Server busca interbloqueos cada 5 segundos y elimina la consulta que es más fácil de revertir, pudimos ver emerger a la víctima del interbloqueo.

En una situación simple, se aplica el consejo más general, y es tocar las tablas en el mismo orden cada vez que se construyen consultas. Por lo general, esto evitará que las consultas se bloqueen entre sí.

¿Qué pasa con las consultas más complejas? Para este escenario, Brent usó una situación más realista que podría surgir fácilmente en Stack Overflow, donde dos personas votan a favor de las preguntas de los demás. Debido a que los mismos usuarios están involucrados en ambas transacciones, esto provoca un interbloqueo.

Aquí, no es suficiente trabajar en cada mesa en el mismo orden cada vez, sino que también es necesario minimizar la cantidad de veces que se toca cada mesa. Como lo explicó Brent, la solución puede involucrar un código feo que hace que las consultas se bloqueen, pero al menos no se bloqueen. En este caso, un bloqueo de corta duración que permita que ambas consultas se ejecuten hasta el final es mejor que un interbloqueo que finalice una de ellas.

Nadie quiere cambiar el código en cientos de consultas, así que céntrese en las que están bloqueadas constantemente, elimine las líneas innecesarias de la transacción y no tenga miedo de introducir un bloque para evitar un bloqueo.