Cause d'un processus étant une victime de blocage
J'ai un processus avec une sélection qui prend beaucoup de temps pour terminer, sur l'ordre de 5 à 10 minutes.
Je n'utilise actuellement pas NOLOCK comme indice pour le moteur de base de données MS SQL.
en même temps, nous avons un autre processus faisant des mises à jour et des insertions dans la même base de données et les mêmes tables.
le premier processus a commencé, récemment pour se terminer prématurément avec un message
SQLEXCEPTION: la Transaction a été bloquée sur les ressources de verrouillage avec un autre processus et a été choisie comme la victime du blocage.
Ce premier processus s'exécute sur d'autres sites dans des conditions identiques mais avec des bases de données plus petites et donc l'instruction select en question prend une période de temps beaucoup plus courte (de l'ordre de 30 secondes environ). Dans ces autres sites, je ne reçois pas le message de blocage dans ces autres sites. Je n'ai pas non plus reçu ce message sur le site qui a le problème au départ, mais, je suppose, comme la base de données a grandi, je crois que j'ai dû en croiser seuil. Voici mes questions:
- Le temps nécessaire à l'exécution d'une transaction pourrait-il rendre le processus associé plus susceptible d'être signalé comme une victime de blocage?
- Si j'exécute le select avec un indice NOLOCK, cela supprimera-t-il le problème?
- je soupçonne qu'un champ datetime vérifié dans le cadre de la clause WHERE dans l'instruction select provoque le temps de recherche lent. Puis-je créer un index basé sur ce champ? Est-il conseillé?
3 réponses
Q1: Le temps nécessaire à l'exécution d'une transaction pourrait-il rendre le processus associé plus susceptible d'être signalé comme une victime de blocage?
Non. Le SELECT est la victime car il n'avait que des données lues, donc la transaction a un coût inférieur associé à elle est donc choisie comme victime:
Par défaut, le moteur de base de données choisit comme victime session exécutant la transaction qui est la moins coûteuse à annuler . Alternativement, un utilisateur peut spécifier la priorité des sessions dans un situation de blocage en utilisant le
SET DEADLOCK_PRIORITY
déclaration. DEADLOCK_PRIORITY peut être défini sur LOW, NORMAL ou HIGH, ou alternativement peut être défini sur n'importe quelle valeur entière dans la plage (-10 à 10).
T2. Si j'exécute le select avec un indice NOLOCK, cela supprimera-t-il le problème?
Non. Pour plusieurs raisons:
- Vous devriez d'abord essayer d'éliminer l'impasse correctement, en enquêtant la cause profonde
- les lectures sales sont des lectures incohérentes .
- la bonne façon de spécifier les lectures Sales est d'utiliser les niveaux d'isolement de transaction
- , il est une bien meilleure solution: read committed.
T3. Je soupçonne qu'un champ datetime vérifié dans le cadre de la clause WHERE dans l'instruction select provoque le temps de recherche lent. Puis-je créer un index basé sur ce champ? Est-il conseillé?
Probablement. La cause de l'impasse est presque très susceptible d'être une base de données mal indexée.Les requêtes de 10 minutes sont acceptables dans des conditions aussi étroites, que je suis sûr à 100% que votre cas n'est pas acceptable.
Avec une confiance de 99%, je déclare que votre Blocage est bloqué par une analyse de grande table en conflit avec les mises à jour. Commencez par capturer le graphique de blocage pour analyser la cause. Vous devrez très probablement optimiser le schéma de votre la base de données. Avant de faire toute modification, lisez cette rubrique concevoir des index et les sous-articles.
Voici comment ce problème de blocage particulier s'est réellement produit et comment il a été résolu. C'est une base de données assez active avec des transactions 130K se produisant quotidiennement. Les index des tables de cette base de données étaient initialement regroupés. Le client nous a demandé de rendre les index non clustered. Dès que nous l'avons fait, l'impasse a commencé. Lorsque nous avons rétabli les index en cluster, l'impasse s'est arrêtée.
Les réponses ici valent la peine d'être essayées, mais vous devriez également revoir votre code. Spécifiquement avoir une lecture de la réponse de Polyfun ici: Comment se débarrasser de l'impasse dans une application SQL Server 2005 et c#?
Il explique le problème de concurrence, et comment l'utilisation de "with (updlock)" dans vos requêtes pourrait corriger votre situation de blocage - en fonction de ce que fait exactement votre code. Si votre code suit Ce modèle, c'est probablement une meilleure solution à faire, avant de recourir à lectures sales, etc.