Je suis dans le domaine de la création de sites Web et d'applications qui ne sont pas critiques -> par exemple. logiciel bancaire, vol spatial, application de suivi de soins intensifs, etc. Vous voyez l'idée.
Donc, avec cette énorme clause de non-responsabilité, est-ce mal d'utiliser l'indication NOLOCK dans une instruction SQL? Il y a quelques années, un collègue administrateur Sql m'a suggéré d'utiliser NOLOCK si je suis satisfait d'une «lecture sale» qui me donnera un peu plus de performances sur mon système car chaque lecture ne verrouille pas le table / ligne / peu importe.
On m'a également dit que c'était une excellente solution si je rencontrais des impasses. Donc, j'ai commencé à suivre cette pensée pendant quelques années jusqu'à ce qu'un gourou Sql m'aide avec du code aléatoire et remarque tous les NOLOCKS dans mon code SQL. J'ai été poliment grondé et il a essayé de me l'expliquer (pourquoi ce n'est pas une bonne chose) et je me suis un peu perdu. J'ai senti que l'essence de son explication était «c'est une solution de fortune à un problème plus grave… surtout si vous êtes dans une impasse. En tant que tel, corrigez la racine du problème '.
J'ai récemment cherché sur Google à ce sujet et je suis tombé sur ce post .
Alors, est-ce que certains Sensei de SQL DB Guru peuvent m'éclairer?
la source
Réponses:
Avec l'indicateur NOLOCK, le niveau d'isolement de transaction pour l'
SELECT
instruction estREAD UNCOMMITTED
. Cela signifie que la requête peut voir des données sales et incohérentes.Ce n'est pas une bonne idée d'appliquer en règle générale. Même si ce comportement de lecture sale convient à votre application Web critique, une analyse NOLOCK peut provoquer une erreur 601 qui mettra fin à la requête en raison du mouvement des données en raison du manque de protection de verrouillage.
Je suggère de lire When Snapshot Isolation Helps and When It Hurts - le MSDN recommande d'utiliser READ COMMITTED SNAPSHOT plutôt que SNAPSHOT dans la plupart des circonstances.
la source
Avant de travailler sur Stack Overflow, j'étais contre
NOLOCK
le principe avec lequel vous pourriez potentiellement effectuer unSELECT
avecNOLOCK
et obtenir des résultats avec des données qui peuvent être obsolètes ou incohérentes. Un facteur à prendre en compte est le nombre d'enregistrements qui peuvent être insérés / mis à jour en même temps qu'un autre processus peut sélectionner des données dans la même table. Si cela se produit souvent, il y a une forte probabilité de blocages, sauf si vous utilisez un mode de base de données tel queREAD COMMITED SNAPSHOT
.Depuis, j'ai changé ma perspective sur l'utilisation de
NOLOCK
après avoir vu comment il peut améliorer lesSELECT
performances et éliminer les blocages sur un serveur SQL massivement chargé. Il y a des moments où vous ne vous souciez pas du fait que vos données ne sont pas exactement engagées à 100% et que vous avez besoin de résultats rapidement, même s'ils ne sont pas à jour.Posez-vous une question lorsque vous envisagez d'utiliser
NOLOCK
:Si la réponse est non, utilisez
NOLOCK
pour améliorer les performances.Je viens d'effectuer une recherche rapide du
NOLOCK
mot - clé dans la base de code de Stack Overflow et j'ai trouvé 138 instances, nous l'utilisons donc dans de nombreux endroits.la source
NOLOCK
. Cela signifie que je dois voter contre votre réponse. Désolé.SELECT
, en lecture uniquement à partir d'un index de couverture, peut provoquer un blocage. SPID 1) commencez a àSELECT
partir de l'index de couverture. SPID 2) Démarrez unUPDATE
de la table. La mise à jour passe ensuite à la mise à jour de l'index de couverture.UPDATE
atteint une plage d'index verrouillée parSELECT
et devient bloquée. SPID 1) recherche toujours dans l'index de couverture, trouve une plage verrouillée par leUPDATE
et devient bloquée. DEADLOCK . Rien ne peut résoudre ce blocage (à l'exception de la capture de l'erreur SQL Server 1205 et d'une nouvelle tentative automatique ou de l'utilisationNOLOCK
)Si vous ne vous souciez pas des lectures sales (c'est-à-dire dans une situation de LECTURE prédominante), alors
NOLOCK
c'est bien.MAIS , sachez que la majorité des problèmes de verrouillage sont dus à l'absence d'index «corrects» pour votre charge de travail de requête (en supposant que le matériel soit à la hauteur de la tâche).
Et l'explication du gourou était correcte. Il s'agit généralement d'une solution temporaire à un problème plus grave.
Edit : Je ne suggère certainement pas que NOLOCK devrait être utilisé. J'imagine que j'aurais dû le dire clairement. (Je ne l'utiliserais jamais, dans des circonstances extrêmes où j'avais analysé que c'était OK). A titre d'exemple, il y a quelque temps, j'ai travaillé sur un TSQL qui avait été saupoudré de NOLOCK pour essayer d'atténuer les problèmes de verrouillage. Je les ai tous supprimés, implémenté les index corrects et TOUS les blocages ont disparu.
la source
Je doute que c'était un "gourou" qui avait eu une expérience dans le trafic élevé ...
Les sites Web sont généralement «sales» au moment où la personne consulte la page complètement chargée. Considérez un formulaire qui se charge à partir de la base de données, puis enregistre les données modifiées ?? C'est idiot la façon dont les gens disent que les lectures sales sont un non non.
Cela dit, si vous avez un certain nombre de couches qui s'appuient sur vos sélections, vous pourriez créer une redondance dangereuse. Si vous avez affaire à de l'argent ou des scénarios de statut, alors vous avez besoin non seulement de données transactionnelles en lecture / écriture, mais d'une solution de concurrence appropriée (ce que la plupart des «gourous» ne dérangent pas).
D'un autre côté, si vous avez une recherche avancée de produits pour un site Web (c'est-à-dire quelque chose qui ne sera probablement pas mis en cache et qui sera un peu intensif) et que vous avez déjà créé un site avec plus de quelques utilisateurs simultanés (phénominal combien "experts" ne l'ont pas fait), il est ridicule d'étouffer tous les autres processus derrière lui.
Sachez ce que cela signifie et utilisez-le le cas échéant. Votre base de données sera presque toujours votre principal goulot d'étranglement de nos jours et l'utilisation intelligente de NOLOCK peut vous faire économiser des milliers d'infrastructures.
EDIT: Ce n'est pas seulement les blocages que cela aide, c'est aussi à quel point vous allez faire attendre tout le monde jusqu'à ce que vous ayez terminé, ou vice versa.
Utilisation de NOLOCK Hint dans EF4?
la source
Aucune des réponses n'est fausse, mais peut-être un peu déroutante.
la source
En tant que développeur professionnel, je dirais que cela dépend. Mais je suis définitivement les conseils de l'AGCS et de l'OMG Ponies. Sachez ce que vous faites, sachez quand cela aide et quand cela fait mal et
lire des astuces et autres mauvaises idées
ce qui pourrait vous faire comprendre le serveur SQL plus en profondeur. Je suis généralement la règle selon laquelle les conseils SQL sont MAUVAIS, mais malheureusement je les utilise de temps en temps quand j'en ai marre de forcer le serveur SQL à faire des choses ... Mais ce sont des cas rares.
Luke
la source
Lorsque le support d'application voulait répondre aux requêtes ad-hock du serveur de production à l'aide de SSMS (qui n'étaient pas pris en charge via les rapports), j'ai demandé qu'ils utilisent nolock. De cette façon, l'activité «principale» n'est pas affectée.
la source
Je suis d'accord avec certains commentaires sur l'indice NOLOCK et en particulier avec ceux qui disent "utilisez-le quand c'est approprié". Si l'application est mal écrite et utilise une méthode d'accès concurrentielle inappropriée, cela peut provoquer une escalade de verrouillage. Les tables hautement transactionnelles sont également verrouillées tout le temps en raison de leur nature. Avoir une bonne couverture d'index n'aidera pas à récupérer les données, mais définir ISOLATION LEVEL sur READ UNCOMMITTED le fait. Je crois également que l'utilisation de l'indice NOLOCK est sûre dans de nombreux cas lorsque la nature des changements est prévisible. Par exemple, dans la fabrication, lorsque les travaux avec les voyageurs passent par différents processus avec de nombreuses insertions de mesures, vous pouvez exécuter en toute sécurité une requête sur le travail terminé avec l'indicateur NOLOCK et ainsi éviter les collisions avec d'autres sessions qui mettent des verrous PROMOTIONNÉS ou EXCLUSIFS sur la table /page. Les données auxquelles vous accédez dans ce cas sont statiques, mais elles peuvent résider dans une table très transactionnelle avec des centaines de millions d'enregistrements et des milliers de mises à jour / insertions par minute. À votre santé
la source
Je pense qu'il n'est pratiquement jamais correct d'utiliser nolock.
Si vous lisez une seule ligne, l'index correct signifie que vous n'aurez pas besoin de NOLOCK car les actions individuelles sur les lignes sont terminées rapidement.
Si vous lisez de nombreuses lignes pour autre chose qu'un affichage temporaire et que vous vous souciez de pouvoir répéter le résultat ou de vous défendre par le nombre produit, alors NOLOCK n'est pas approprié.
NOLOCK est une balise de substitution pour "je ne me soucie pas si cette réponse contient des lignes en double, des lignes qui sont supprimées ou des lignes qui n'ont jamais été insérées au départ en raison de la restauration"
Erreurs possibles sous NOLOCK:
Toute action qui peut provoquer une division de page pendant l'exécution de la sélection noLock peut provoquer ces événements. Presque toutes les actions (même une suppression) peuvent provoquer un fractionnement de page.
Par conséquent: si vous «savez» que la ligne ne sera pas modifiée pendant que vous exécutez, n'utilisez pas nolock, car un index permettra une récupération efficace.
Si vous pensez que la ligne peut changer pendant l'exécution de la requête et que vous vous souciez de la précision, n'utilisez pas nolock.
Si vous envisagez NOLOCK en raison de blocages, examinez la structure du plan de requête pour des analyses de table inattendues, retracez les blocages et voyez pourquoi ils se produisent. NOLOCK autour des écritures peut signifier que les requêtes précédemment bloquées écriront potentiellement toutes les deux la mauvaise réponse.
la source
Les meilleures solutions, lorsque cela est possible, sont:
Le niveau d'isolement de transaction SNAPSHOT a été créé car MS perdait des ventes au profit d'Oracle. Oracle utilise des journaux d'annulation / rétablissement pour éviter ce problème. Postgres utilise MVCC. À l'avenir, Heckaton de MS utilisera MVCC, mais il reste des années avant d'être prêt pour la production.
la source
NOLOCK est souvent exploité comme un moyen magique d'accélérer les lectures de bases de données, mais j'essaie d'éviter de l'utiliser autant que possible.
L'ensemble de résultats peut contenir des lignes qui n'ont pas encore été validées, qui sont souvent annulées ultérieurement.
Une erreur ou un ensemble de résultats peut être vide, contenir des lignes manquantes ou afficher la même ligne plusieurs fois.
En effet, d'autres transactions déplacent des données en même temps que vous les lisez.
READ COMMITTED ajoute un problème supplémentaire où les données sont corrompues dans une seule colonne où plusieurs utilisateurs modifient la même cellule simultanément.
la source
Dans la vraie vie où vous rencontrez des systèmes déjà écrits et que l'ajout d'index aux tables ralentit considérablement le chargement des données d'une table de données 14gig, vous êtes parfois obligé d'utiliser WITH NOLOCK sur vos rapports et de procéder à la fin du mois pour que les fonctions agrégées (somme , count, etc.) ne font pas de verrouillage de ligne, de page, de tableau et nuisent à la performance globale. Facile à dire dans un nouveau système, n'utilisez jamais WITH NOLOCK et utilisez des index - mais l'ajout d'index réduit considérablement le chargement des données, et quand on me dit, eh bien, modifiez la base de code pour supprimer les index, puis chargez en masse puis recréez les index - ce qui tout va bien si vous développez un nouveau système. Mais pas lorsque vous avez déjà un système en place.
la source