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

Bloqueo de SQL con operaciones de selección/actualización en una tabla

Las dos consultas que causan el interbloqueo son SELECT a continuación (process id="process3980de4558" ):

select @existing = team_it_cube_attr_05 from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key

Y el UPDATE consulta a continuación (process id="process386ed48188" ):

UPDATE D
SET D.team_rss_attr_01 = LEFT(S.mkt_prodchar_13,25)...

El <resource-list> la sección señala el SELECT consulta poseía un bloqueo exclusivo (X) en una página e intentaba adquirir un bloqueo de intención compartida (IS) en otra página mientras leía datos. La UPDATE la consulta ya poseía un bloqueo IS y estaba intentando adquirir un bloqueo X en una página para realizar la actualización.

Dada la combinación contra esta tabla:

...from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key...
...INNER JOIN tbl_Ref_Attr_Prod_Team D ON D.prod_key=P.prod_key...

El SELECT la consulta ya posee un bloqueo exclusivo. Esto probablemente significa que es parte de una transacción más grande que ya ha realizado una UPDATE en una consulta previa. Los bloqueos de consultas anteriores se mantendrán para preservar la integridad de los datos durante la transacción (según el nivel de aislamiento de transacciones ).

La UPDATE la consulta necesita leer la tabla tbl_Ref_Attr_Prod_team . Adquiere bloqueos de intención compartida en páginas y filas mientras lee datos. Cuando el UPDATE consulta encuentra las filas coincidentes, intentará convertir los bloqueos IS en bloqueos X. Los bloqueos IS no son compatibles con los bloqueos X. Porque el SELECT la consulta ya tiene un bloqueo IS en una o más de esas páginas, las consultas se interbloquean entre sí.

Una posible causa sería la falta de índices en tbl_Ref_Attr_Prod_team.prod_key . Sin un índice en esta columna, UPDATE la consulta escaneará todas las filas de la tabla tbl_Ref_Attr_Prod_team .

Incluso si existe un índice en prod_key , si hay una pequeña cantidad de filas en la tabla, SQL Server puede decidir que el rendimiento sería mejor si la consulta explorara toda la tabla en lugar de buscar el índice. Registrar el plan de consulta cuando ocurre el interbloqueo verificaría esta teoría.

Nos encontramos con puntos muertos de tablas pequeñas regularmente cuando preparamos nuevas bases de datos. Inicialmente, las tablas son pequeñas y los recorridos de las tablas provocan todo tipo de interbloqueos. Posteriormente, cuando las tablas son más grandes, el costo calculado de escanear la tabla supera el costo de buscar el índice y ya no se producen interbloqueos. En entornos de prueba donde el número de filas siempre es pequeño, hemos recurrido al uso de FORESEEK y WITH INDEX sugerencias para forzar búsquedas de índice en lugar de escaneos. Esperamos poder forzar planes de consulta a través de la función de almacenamiento de consultas de SQL Server 2016.