Les deux requêtes provoquant le blocage sont le SELECT
ci-dessous (process id="process3980de4558"
):
select @existing = team_it_cube_attr_05 from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key
Et la UPDATE
requête ci-dessous (process id="process386ed48188"
):
UPDATE D
SET D.team_rss_attr_01 = LEFT(S.mkt_prodchar_13,25)...
Le <resource-list>
la section note le SELECT
requête possédait un verrou exclusif (X) sur une page et essayait d'acquérir un verrou intentionnel partagé (IS) sur une autre page pendant qu'elle lisait des données. La UPDATE
requête possédait déjà un verrou IS et essayait d'acquérir un verrou X sur une page pour effectuer la mise à jour.
Étant donné la jointure avec cette table :
...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...
Le SELECT
la requête possède déjà un verrou exclusif. Cela signifie probablement qu'il fait partie d'une transaction plus importante qui a déjà effectué une UPDATE
dans une requête préalable. Les verrous des requêtes précédentes seront conservés pour préserver l'intégrité des données pendant la transaction (selon le niveau d'isolement des transactions
).
La UPDATE
la requête doit lire la table tbl_Ref_Attr_Prod_team
. Il acquiert des verrous partagés par intention sur les pages et les lignes lors de la lecture des données. Lorsque la UPDATE
requête trouve les lignes correspondantes, elle tentera de convertir les verrous IS en verrous X. Les verrous IS ne sont pas compatibles avec les verrous X. Parce que le SELECT
requête a déjà un verrou IS sur une ou plusieurs de ces pages, les requêtes se bloquent les unes avec les autres.
Une cause possible serait des index manquants sur tbl_Ref_Attr_Prod_team.prod_key
. Sans index sur cette colonne, le UPDATE
la requête analysera toutes les lignes de la table tbl_Ref_Attr_Prod_team
.
Même si un index existe sur prod_key
, s'il y a un petit nombre de lignes dans la table, SQL Server peut décider que les performances seraient meilleures si la requête analysait la table entière au lieu de rechercher l'index. L'enregistrement du plan de requête lorsque le blocage se produit vérifierait cette théorie.
Nous rencontrons régulièrement de petits blocages de table lors de la mise en place de nouvelles bases de données. Au départ, les tables sont minuscules et les balayages de table provoquent toutes sortes de blocages. Plus tard, lorsque les tables sont plus volumineuses, le coût calculé de l'analyse de la table dépasse le coût de la recherche de l'index, et les interblocages ne se produisent plus. Dans les environnements de test où le nombre de lignes est toujours petit, nous avons eu recours à FORESEEK
et WITH INDEX
conseils pour forcer les recherches d'index au lieu des analyses. Nous sommes impatients de pouvoir forcer les plans de requête via la fonctionnalité de magasin de requêtes de SQL Server 2016.