2010-09-24 7 views
118

Contexte: J'ai une requête critique pour les performances que je voudrais exécuter et je me fiche des lectures incorrectes.SQL Server NOLOCK et jointures

Ma question est; Si j'utilise des jointures, dois-je spécifier l'indice NOLOCK sur celles-ci?

Par exemple; est:

SELECT * FROM table1 a WITH (NOLOCK) 
INNER JOIN table2 b WITH (NOLOCK) ON a.ID = b.ID 

équivalent à:

SELECT * FROM table1 a WITH (NOLOCK) 
INNER JOIN table2 b ON a.ID = b.ID 

Ou dois-je préciser l'indication (NOLOCK) sur la jointure pour assurer que je ne suis pas le verrouillage de la table jointe?

Répondre

116

Je ne vais pas aborder l'argument READ UNCOMMITTED, juste votre question originale. Oui, vous avez besoin de WITH(NOLOCK) sur chaque table de la jointure. Non, vos requêtes ne sont pas identiques.

Essayez cet exercice. Commencez une transaction et insérez une ligne dans table1 et table2. Ne pas valider ou annuler la transaction pour le moment.À ce stade, votre première requête retournera avec succès et inclura les lignes non validées; votre deuxième requête ne retournera pas parce que table2 n'a pas l'indice WITH(NOLOCK) dessus.

+1

merci pour la réponse concise, juste ce que je cherchais dans ce cas. – DanP

14

J'étais assez sûr que vous devez spécifier le NOLOCK pour chaque JOIN dans la requête. Mais mon expérience a été limitée à SQL Server 2005.

Lorsque j'ai recherché MSDN juste pour confirmer, je n'ai rien trouvé de précis. Les énoncés ci-dessous ne semblent me faire penser que pour 2008, vos deux déclarations ci-dessus sont équivalentes mais pour 2005, il est pas le cas:

[SQL Server 2008 R2]

Tous verrouillent conseils sont propagées à toutes les tables et vues qui sont accédées par le plan de requête, y compris les tables et les vues référencées dans une vue. SQL Server effectue également les contrôles de cohérence de verrouillage correspondants.

[SQL Server 2005]

Dans SQL Server 2005, tous les conseils de verrouillage sont propagées à toutes les tables et vues référencées dans une vue. SQL Server effectue également les contrôles de cohérence de verrouillage correspondants.

De plus, point à noter - et cela vaut pour 2005 et 2008:

Le tableau des notes sont ignorées si la table est accessible par le plan de requête. Cela peut être dû au fait que l'optimiseur a choisi de ne pas accéder à la table ou d'accéder à une vue indexée à la place. Dans ce dernier cas, l'accès à une vue indexée peut être évité en utilisant l'indicateur de requête OPTION (EXPAND VIEWS).

+0

@In Sane: Intéressant ... merci pour cela ... Je suppose que je ne fais aucun mal en l'incluant sur les JOINS, même si ce n'est pas entièrement nécessaire? La documentation sur NOLOCK est assez clairsemée comme vous l'avez mentionné; J'ai eu du mal à trouver quelque chose de concluant moi-même. – DanP

+2

@InSane: D'où avez-vous eu cette information? Cela semble aller à l'encontre de la réponse acceptée. –

+0

@notfed - se référer technet lien http://technet.microsoft.com/en-us/library/ms187373(v=sql.105).aspx - vous pouvez changer la version de la base de données en haut pour comparer le même article pour différentes versions de le db – InSane

8

Aucune. Vous définissez le niveau d'isolement à READ UNCOMMITTED, ce qui est toujours préférable à donner des indications de verrouillage individuelles. Ou, mieux encore, si vous vous souciez de détails comme consistency, utilisez snapshot isolation.

+0

@Remus: Je ne suis pas sûr de pouvoir utiliser READ UNCOMMITTED dans mon cas car j'accède à la connexion via NHibernate pour effectuer un appel ADO.NET brut spécial; cela peut-il être spécifié en ligne dans la requête, ou va-t-il obéir au niveau de transaction présent sur la transaction NHibernate? – DanP

+0

Enveloppez l'appel dans 'using (TransactionScope scope = new TransactionScope (..., TransactionOptions) {...}' et définissez 'IsolationLevel' sur les options: http://msdn.microsoft.com/fr-fr/ library/system.transactions.transactionoptions.isolationlevel.aspx –

+0

@Remus: Malheureusement, la gestion des transactions est prise en charge à un niveau beaucoup plus élevé que celui-ci, donc ce n'est pas non plus une option – DanP