Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Pourquoi cette requête SQL Server est-elle bloquée ?

  • le processus 9196a8 a la page 151867 emplacement 174 en mode X et veut la page 140302 emplacement 31 en mode S
  • le processus 88b5b8 a la page 140302 emplacement 31 en mode X et veut la page 151867 emplacement 174 en mode S
  • les deux suppressions s'exécutent sous isolationlevel="repeatable read (3)"

Ainsi, le blocage se produit sur le tas de base de la table (les verrous RID au lieu des verrous à clé impliquent un tas et non un Btree). Le niveau d'isolation élevé (probablement causé par DTC, à en juger par le nom xact) rend le paramètre RCSI non pertinent.

De quel type sont les colonnes PARTYEXTERNALREF et PARTYTYPE ? Les paramètres transmis sont NVARCHAR (c'est-à-dire Unicode) et si les colonnes sont VARCHAR (c'est-à-dire Ascii) alors en raison des règles de priorité des types de données l'indice NC ne serait pas utilisé. En raison de l'analyse de table impliquée, ainsi que du niveau d'isolement élevé utilisé, un blocage est presque inévitable.

La solution serait d'utiliser des paramètres de type VARCHAR pour @P0 et @P1 afin que l'index NC soit exploité pour éviter le balayage de la table.

Si les paramètres sont déjà de type VARCHAR et que vous pouvez confirmer à partir du plan d'exécution qu'une recherche sur le NC est utilisée, ma première question serait quoi autre est la transaction en cours, autre que les instructions de suppression ?

BTW, vous ne donnez que le nom de l'index NC mais je suppose qu'il est sur (PARTYEXTERNALREF, ISCOUNTERPARTY, PARTYID) .

Mettre à jour

Puisque votre commentaire dit que les colonnes sont NVARCHAR alors l'hypothèse d'analyse des tables est probablement erronée. Il existe trois autres possibilités de provoquer un blocage nécessitant une enquête :

  • toute autre instruction exécutée par la transaction avant DELETE (c'est la plus probable)
  • tout chevauchement dans les lignes sélectionnées par deux instructions DELETE impliquées dans le blocage
  • collision de hachage

Pour les deux premières hypothèses, vous pouvez faire n'importe quoi maintenant (vérifiez si elles sont correctes). Pour le dernier je peux vous dire comment le vérifier, mais ce n'est pas anodin. Il est peu probable que cela se produise et un peu difficile à prouver, mais c'est possible. Puisque vous connaissez le cas d'impasse (le XML joint), utilisez-le comme base d'investigation :

  • restaurer une copie ponctuelle de la base de données avec arrêt à 2011-09-02T19:00:29.690
  • exécuter DBCC TRACEON(3604,-1)
  • en utilisant DBCC PAGE (<restored db id>, 1, 151867, 3) inspecter les valeurs dans l'emplacement 174
  • à l'aide de DBCC PAGE(, 1, 140302, 3)` inspectez les valeurs à l'emplacement 31
  • exécutez SELECT %%lockres%% FROM PARTIES WHERE PARTYEXTERNALREF = ... AND ISCOUNTERPARTY='N' and PARTYID=... et transmettez les valeurs lues ci-dessus
  • compare les valeurs de hachage de verrouillage résultantes, si elles correspondent, vous avez une collision de hachage et cela a provoqué le blocage.