NOLOCK est-il toujours mauvais?


34

Je suis un développeur de rapports qui souhaite rendre mes requêtes aussi efficaces que possible. Auparavant, je travaillais avec un administrateur de base de données qui me disait - je crois parce que je traitais toujours des rapports sur un serveur de production - que je pouvais utiliser NOLOCKdans chaque requête.

Maintenant, je travaille avec un administrateur de base de données qui a interdit NOLOCKtoutes les situations, même lorsqu'un de mes rapports (en raison d'un manque considérable d'index sur quelques tables) interrompt la réplication et les mises à jour du système. À mon avis, dans ce cas, un NOLOCKserait une bonne chose.

Étant donné que la plupart de mes formations SQL sont venues de divers administrateurs de bases de données avec des opinions très différentes, je voulais poser cette question à un large éventail d’administrateurs de bases de données.


Réponses:


30

Si votre rapport bloque les mises à jour que votre DBA a raison: vous ne devez absolument pas utiliser NOLOCK. Le fait qu'il ya des conflits est une indication claire que si vous voulez utiliser sale vous lit obtiendrez des rapports incorrects.

À mon avis, il existe toujours de meilleures alternatives que NOLOCK:

  • Vos tables de production sont-elles en lecture seule et ne sont-elles jamais modifiées? Marquez la base de données en lecture seule!
  • Les analyses de table provoquent des conflits de verrous? Indexez les tables de manière appropriée, les avantages sont multiples.
  • Vous ne pouvez pas modifier / je ne sais pas comment indexer correctement? Utilisez l’ ISOLEMENT DE SNAPSHOT .
  • Impossible de modifier l'application pour utiliser l'instantané? Activer l' instantané lu commis !
  • Vous avez mesuré l’impact de la gestion des versions de ligne et avez des preuves qu’il a un impact sur les performances? Vous ne pouvez pas indexer les données? et vous êtes d'accord avec les rapports incorrects ? Alors, à tout le moins, faites-vous une faveur et utilisez-le SET TRANSACTION ISOLATION LEVEL, pas un indice de requête. Il sera plus facile de fixer ultérieurement le niveau d’isolation au lieu de modifier chaque requête.

6
Faites attention: l'activation de l'instantané en lecture seule peut endommager du code.
AK

33

Ce n'est pas toujours mauvais.

Bien sûr, cela vous permet de lire des valeurs non validées (qui peuvent être annulées et donc jamais logiquement exister) ainsi que permettre des phénomènes tels que la lecture de valeurs plusieurs fois ou pas du tout.

Les seuls niveaux d'isolation qui garantissent que vous ne rencontrez pas de telles anomalies sont sérialisables / instantanés. Des valeurs de lecture sous Répétable peuvent être manquées si une ligne est déplacée (en raison d'une mise à jour de clé) avant que l'analyse n'atteigne cette ligne. Les valeurs sous lecture validée peuvent être lues deux fois si une mise à jour de clé entraîne le déplacement d'une ligne précédemment lue.

nolockToutefois, ces problèmes sont plus susceptibles de se produire car, par défaut, à ce niveau d’isolement, il utilisera une analyse d’allocation ordonnée lorsqu’il estime qu’il reste plus de 64 pages à lire . En plus de la catégorie de problèmes qui surviennent lorsque les lignes se déplacent d'une page à l'autre en raison de mises à jour de clé d'index, ces analyses par affectation ordonnée sont également vulnérables aux problèmes de fractionnements de page (des lignes peuvent être omises si la nouvelle page allouée est antérieure au point déjà numérisé ou lu deux fois si une page déjà numérisée est divisée en une page ultérieure du fichier).

Au moins pour les requêtes simples (une seule table), il est possible de décourager l'utilisation de ces analyses et d'obtenir une analyse ordonnée par clé nolocken ajoutant simplement un ORDER BY index_keyà la requête de sorte que la Orderedpropriété IndexScanis true.

Mais si votre application de reporting n'a pas besoin de chiffres absolument précis et peut tolérer la plus grande probabilité d'incohérences, elle pourrait être acceptable.

Mais vous ne devriez certainement pas lancer toutes les requêtes dans l’espoir qu’il s’agisse d’un bouton «turbo» magique. En plus de la probabilité plus grande de rencontrer des résultats anormaux à ce niveau d'isolement ou en l'absence de tout résultat (erreur "Impossible de poursuivre l'analyse avec NOLOCK en raison du transfert de données"), il existe même des cas où les performances nolock peuvent être bien pires .


3
+1 - Nous l'utilisons beaucoup car nos tables de production ne sont jamais modifiées.
JNK

@JNK Qu'entendez-vous par jamais modifié?
Kuberchaun

4
Martin, je suggérerais des mots légèrement différents: "les valeurs engagées en lecture peuvent être manquées et lues plus d'une fois". On peut récupérer une ligne plus de deux fois dans certains cas exotiques.
AK

@ StarShip3000 Les données que nous déployons en production sont fondamentalement en lecture seule pour les utilisateurs finaux. La plupart de leurs points de vue ont donc des indices NOLOCK
JNK

11

Vos clients tolèrent-ils des résultats incohérents dans les rapports? Si la réponse est non, vous ne devriez pas utiliser NOLOCK - vous pouvez obtenir des résultats erronés en cas de simultanéité. J'ai écrit quelques exemples ici , ici et ici . Ces exemples montrent des résultats incohérents sous READ COMMITTED et REPEATABLE READ, mais vous pouvez les modifier et obtenir des résultats erronés avec NOLOCK.


La plupart des rapports que je crée ne sont pas exécutés sur les données actuelles. Les rapports de la plupart des clients sont ceux d'hier. Votre réponse changerait-elle si c'était le cas?
DataGirl

8

La plupart des rapports que je crée ne sont pas exécutés sur les données actuelles. Les rapports de la plupart des clients sont ceux d'hier. Votre réponse changerait-elle si c'était le cas?

Si tel est le cas, vous disposez d'une option supplémentaire: au
lieu d'exécuter vos requêtes sur la base de données de production et de manipuler les verrous NOLOCK, vous pouvez créer vos rapports à partir d'une copie de la base de données de production.

Vous pouvez le configurer pour qu'il soit automatiquement restauré à partir d'une sauvegarde chaque nuit .
Apparemment, vos rapports sont exécutés sur des serveurs situés sur les sites des clients. Je ne sais donc pas si cette solution serait une solution viable pour vous.
(mais encore une fois ... ils devraient quand même avoir des sauvegardes, donc il ne vous faut que de l'espace serveur pour les restaurer)

Je suis un développeur interne, ce qui me facilite la tâche car je contrôle entièrement les serveurs et les bases de données.

Vous pouvez le faire au moins pour les rapports qui nécessitent uniquement des données d’hier et plus anciennes. Certains rapports devront peut-être rester dans la base de données de production, mais au moins vous transférez une partie de la charge vers une autre base de données (ou mieux, un autre serveur).

La situation est la même au travail:
nous utilisons une copie de la base de données de production comme celle-ci pour presque tous les éléments de rapport, mais quelques requêtes nécessitent des données actuelles.


J'aime votre réponse et cela fonctionnerait - si j'avais le contrôle total - ce que je n'ai pas fait. Souvent, je n'ai pas le contrôle total et je ne peux pas créer d'index. J'ai de la chance si je peux exécuter / afficher les plans d'exécution.
DataGirl
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.