Quand est-il approprié D'utiliser NOLOCK?

j'ai de temps en temps des problèmes de temporisation et des blocages avec des requêtes de longue durée.

je me demande quand et Où utiliser NOLOCK?

Dois-je l'utiliser sur les mises à jour et inserts? ou lit?

9
demandé sur Brian Hedler 2009-05-03 13:14:07

6 réponses

Notez que vous pouvez spécifier nolock sur une base par table.

j'ai typiquement utilisé nolock dans les requêtes de sélection complexes, mais seulement pour les petites tables de recherche qui n'ont presque jamais changé, et pour les données d'Affichage Seulement. Vous savez les tables qui énumèrent les prix pour le semestre en cours, ou des recherches d'ids à des chaînes etc. Des choses qui ne changent qu'avec des mises à jour majeures après lesquelles les serveurs sont généralement redémarrés de façon routinière de toute façon.

cette amélioration performance significativement, réduit les chances d'impasse dans les temps les plus occupés, et plus important encore, il était vraiment perceptible au cours des moments les plus mauvais pour les requêtes qui ont touché un grand nombre de tables (ce qui est logique, ils doivent obtenir moins de serrures, et ces sidetables sont souvent utilisés presque partout, diminuant souvent de 7-8 à 4 tables qui doivent être verrouillées)

mais faites très attention en l'ajoutant, ne le précipitez pas, et ne le faites pas de façon routinière. Il ne fera pas de mal lorsqu'il est utilisé correctement, mais ça fera terriblement mal quand on l'utilise mal.

ne l'utilisez pas pour des choses très critiques, des choses qui calculent, etc, parce qu'il va devenir incohérent, tout ce qui conduit à une écriture tôt ou tard.

une autre optimisation de ce type est ROWLOCK, qui ne se verrouille qu'au niveau de la rangée. Ceci est principalement utile lors de la mise à jour (ou de la suppression) des tables où les lignes ne sont pas liées entre elles, comme les tables où vous ne mettez que des enregistrements log (et l'ordre dans lequel ils sont insérés n'a pas d'importance). Si vous avez un schéma que quelque part dans la fin d'une transaction un enregistrement de journal est écrit à une certaine table, cela peut accélérer considérablement aussi.

si votre base de données a un pourcentage relativement faible écrit, il pourrait ne pas être la peine. J'avais un ratio lecture:écriture de moins de 2:1.

quelques URLs que j'ai sauvegardées en travaillant sur ceci:

http://www.developerfusion.com/article/1688/sql-server-locks/4/

6
répondu Marco van de Voort 2009-05-03 09:58:04

Il y a quatre niveaux d'isolation de transaction dans SQL Server:

  1. READ UNCOMMITTED
  2. READ COMMITTED
  3. RÉPÉTABLE READ
  4. SERIALISABLE

pour les tableaux auxquels elle s'applique, NOLOCK est l'équivalent de"lire non engagé". Cela signifie que vous pouvez voir les lignes de transactions qui pourraient être repris dans le futur, et de nombreux d'autres résultats étranges.

Encore, nolock fonctionne très bien dans la pratique. En particulier pour les requêtes en lecture seule où l'affichage de données légèrement erronées n'est pas la fin du monde, comme les rapports d'affaires. Je l'éviterais près des mises à jour ou des encarts, ou généralement n'importe où près du code de prise de décision, surtout si elle implique des factures.

comme alternative à nolock, considérons "read committed snapshot", qui est destiné aux bases de données avec une lecture lourde et moins d'écriture activité. Vous pouvez l'allumer avec:

ALTER DATABASE YourDb SET READ_COMMITTED_SNAPSHOT ON;

il est disponible pour SQL Server 2005 et supérieur. C'est ainsi que fonctionne Oracle par défaut, et c'est ce que stackoverflow lui-même utilise. Il y a même un coding horror article de blog à ce sujet.

P.S. longues requêtes en cours d'exécution et deadlocks peut également indiquer SQL Serveur fonctionne avec de fausses hypothèses. Vérifiez si vos statistiques ou index sont périmés:

SELECT 
    object_name = Object_Name(ind.object_id),
    IndexName = ind.name,
    StatisticsDate = STATS_DATE(ind.object_id, ind.index_id)
FROM SYS.INDEXES ind
order by STATS_DATE(ind.object_id, ind.index_id) desc
Les statistiques

devraient être mises à jour dans un plan de maintenance hebdomadaire.

5
répondu Andomar 2009-05-03 10:13:45

utilisez nolock en dernier recours. La plupart des problèmes de blocage peuvent être résolus en réglant les requêtes et/ou en réglant les index. Je pense que j'ai vu une impasse dans les 5 dernières années qui n'a pas pu être corrigée en réglant l'une des deux.

notez également que NOLOCK n'est honoré que sur certaines déclarations. Les modifications de données seront toujours verrouillées, ce comportement ne peut pas être changé. Donc, si vous êtes dans une impasse écrivain/écrivain (assez courant), AUCUNE serrure ne vous aidera pas du tout.

Sachez également que nolock, en plus de renvoyer des données sales, peut entraîner des lignes doubles (lignes lues deux fois à partir du tableau sous-jacent) et des lignes manquantes (lignes dans le tableau sous-jacent qui n'ont pas été lues du tout).

Nolock signifie essentiellement pour SQL Server 'Je ne me soucie pas si mes résultats sont légèrement inexacts'

l'isolement d'Instantané est une option. Assurez-vous juste que vous testez soigneusement d'abord que la charge accrue sur TempDB peut être assez sévère, en fonction la fréquence et la durée de vos transactions. Notez également que même si vous ne verrez pas de blocages dans l'isolation des snapshots, vous pouvez obtenir des conflits de mise à jour. Encore une fois, testez et assurez-vous que vos applications fonctionnent correctement et peuvent gérer toutes les erreurs qu'ils obtiennent.

3
répondu GilaMonster 2009-05-03 19:04:58

utilisez-le lorsqu'il est acceptable d'avoir des lectures erronées et des enregistrements fantômes, c'est-à-dire que vous pouvez avoir des rapports non critiques qui s'exécutent régulièrement lorsque l'exactitude de l'information n'est pas un facteur principal, mais qu'avoir une vue sur le volume des enregistrements Est, ou une autre mesure, par exemple

2
répondu Russ Cam 2009-05-03 09:27:32

vous devez utiliser nolock quand il est correct de lire des données sales. Une transaction importante qui peut apporter un certain nombre de changements à la base de données peut encore être en cours, en utilisant nolock retournera juste les données qu'il a fixé jusqu'à présent. Si cette transaction est annulée, les données que vous regardez pourraient être erronées. Par conséquent, vous ne devez l'utiliser que lorsque cela n'a pas d'importance que ce que vous obtenez en retour pourrait être mal.

Blocages sont un problème commun, mais 9 fois sur 10 sont entièrement causée par un développeur problème. Je voudrais concentrer sur la recherche de la cause des blocages plutôt que d'utiliser nolock. Il est plus que probable qu'il ne s'agisse que d'une seule transaction faisant les choses dans un ordre différent de tous les autres. Réparer juste celui-là peut faire disparaître tous vos problèmes.

2
répondu Robin Day 2009-05-03 09:48:50

pour une vue cohérente sur le plan transactionnel sans serrures de lecture recommande d'activer l'isolation des snapshots dans le serveur SQL.

ceci est légèrement différent de NOLOCK en ce que lorsque vous lisez des informations les résultats reflètent toujours une version de données engagées plutôt que la possibilité de visualiser des données non engagées. Cela fournit la même simultanéité de verrouillage que NOLOCK (pas de serrures "en lecture") avec des résultats plus clairs.

il faut toujours garder à l'esprit, même avec cohérence transactionnelle les données que vous affichez ou utilisez au moment où elles sont affichées peuvent être erronées ou périmées de toute façon. J'ai vu trop de gens supposer que s'ils utilisent les données assez rapidement ou s'ils l'utilisent dans une requête/transaction que c'est OK. C'est absurde -- à mon avis, les niveaux de cohérence reproductibles n'auraient jamais dû être mis en œuvre en premier lieu, car cela encourage simplement le mauvais comportement. Ils n'existent pas dans Oracle.

personnellement J'aime désactiver le verrouillage pour certaines vues et certains rapports de données non critiques, car il impose moins de charge sur le système et la petite probabilité de fournir des résultats légèrement inexacts n'est pas un problème.

tirer profit des niveaux reproductibles de cohérence de lecture et commettre des péchés tels que le fait de conserver des transactions ouvertes pour l'entrée des utilisateurs pourrait être un peu plus facile pour le développeur en termes de développement initial, mais conduira presque toujours à des"blocages" majeurs de route à tout espoir de dimensionnement raisonnable de votre application.

mon point de vue est que la meilleure approche est toujours de" vérifier deux fois " les conditions qui doivent encore être vraies afin d'appliquer des mises à jour à n'importe quelles données.

Mauvais:

UPDATE myaccount SET balance = 2000

mieux:

UPDATE myaccount SET balance = balance + 2000

mieux encore:

UPDATE myaccount SET balance = 2000 WHERE balance = 0 AND accountstatus = 1

enfin, la demande doit vérifier le nombre de lignes pour s'assurer que le nombre prévu de lignes a été effectivement mis à jour avant présentation des commentaires sur le succès à l'utilisateur.

1
répondu Einstein 2010-11-07 10:47:02