2010-06-08 7 views
2

Je regarde la sortie de SP_WhoIsActive sur SQL Server 2005, et il me dit qu'une session en bloque une autre - très bien. Cependant, ils ont tous les deux un SELECT. Comment un SELECT en bloque-t-il un autre? Ne devraient-ils pas tous deux acquérir des verrous partagés (qui sont compatibles les uns avec les autres)?Comment un SELECT en bloque-t-il un autre?

Quelques détails supplémentaires: Aucune session n'a un nombre de transactions ouvert - elles sont donc autonomes.

Les requêtes rejoignent une vue avec une table.

Ce sont des requêtes complexes qui rejoignent beaucoup de tables et aboutissent à environ 10 000 lectures.

Un aperçu très apprécié.

Répondre

4

Les instructions SELECT peuvent bloquer une autre instruction SELECT. Vous pensez probablement que puisque les deux n'acquièrent que des verrous S, ils ne devraient jamais bloquer. Mais le blocage se produit sur différents types de ressources, pas seulement sur les verrous. Un exemple typique est celui des contraintes de mémoire. Je vais essayer de creuser une réponse récente à une question ici qui avait attaché un graphique de blocage qui a montré aux instructions SELECT, l'un pour l'autre pour les ressources de mémoire d'opérateur d'échange parallèle (tampons).

Mise à jour Voici le lien avec les informations de blocage J'ai parlé: I have data about deadlocks, but I can't understand why they occur Si vous étudiez le graphique de blocage, vous remarquerez la ressource suivante dans la liste d'attente:

<exchangeEvent id="Pipe894b0680" WaitType="e_waitPipeGetRow" nodeId="0"> 
    <owner-list> 
    <owner id="process824df048"/> 
    </owner-list> 
    <waiter-list> 
    <waiter id="process86ce0988"/> 
    </waiter-list> 
</exchangeEvent> 

Ce n'est pas un verrou, est une ressource 'e_waitPipeGetRow', appartient à un SELECT et un autre SELECT l'attend. Une discussion sur les ressources parallèles intra-requête peut être trouvée ici: Today's Annoyingly-Unwieldy Term: "Intra-Query Parallel Thread Deadlocks". Alors que la plupart des discussions vont se concentrer sur les problèmes d'interblocage, cela ne signifie pas que le blocage ordinaire ne peut pas se produire sur ces ressources. sys.dm_exec_requests aura l'information appropriée dans wait_type et wait_resource.

+0

merci beaucoup pour cette information! – Krip

1

Je pense que c'est parce que la première sélection effectue un verrouillage de ligne/verrouillage de table. Tout en joignant la table, vous pouvez fournir NO LOCK Hint.

+0

Dans mon expérience aujourd'hui, l'indicateur NO LOCK n'est pas suffisant pour arrêter un véritable interblocage de thread parallèle intra-requête. –

+0

Il est déconseillé d'utiliser NO LOCK. Cela peut conduire à des lectures incorrectes (données dupliquées, données manquantes). Le verrouillage est un mécanisme intentionnel visant à préserver la cohérence des données. Utilisez NO LOCK à vos risques et périls. http://blogs.sqlsentry.com/aaronbertrand/bad-habits-nolock-everywhere/ – Davos