2009-11-12 6 views
17

J'ai vu des instructions SQL en utilisant nolock et (nolock) par exemple -syntaxe pour nolock dans sql

select * from table1 nolock where column1 > 10 

ET

select * from table1 with(nolock) where column1 > 10 

Lequel des énoncés ci-dessus est correcte et pourquoi?

Répondre

6

Ils sont à la fois techniquement correct, mais not using the WITH keyword has been deprecated que de SQL 2005, afin de se habituer à utiliser le mot clé WITH - réponse courte, utilisez le mot clé WITH.

+0

ok donc avec (nolock) est devenu la nouvelle syntaxe depuis sql 2005, bien que nolock fonctionne toujours. est-ce que c'est ça? – seenasan

+0

oui, fonctionne encore sans le "avec", mais il a été déprécié, ce qui signifie qu'il ne fonctionnera pas de cette façon dans une version à un moment donné dans le futur (pourrait être la prochaine version, pourrait être la suivante, pourrait être 10 à partir de maintenant) ... – chadhoc

+0

aussi sur l'insertion, mise à jour devrait avec (nolock) être utilisé là aussi comme une norme de programmation? – seenasan

5

utilisation "AVEC (NOLOCK)".

27

La première déclaration ne se verrouille pas quoi que ce soit, alors que le second fait. Quand je l'ai testé ce tout à l'heure sur SQL Server 2005, dans

select * from table1 nolock where column1 > 10 --INCORRECT 

"nolock" est devenu l'alias, dans cette requête, de table1.

select * from table1 with(nolock) where column1 > 10 

exécute la fonctionnalité nolock souhaitée. Sceptique? Dans une fenêtre distincte, exécutez

BEGIN TRANSACTION 
UPDATE tabl1 
set SomeColumn = 'x' + SomeColumn 

pour verrouiller la table, puis essayez chaque instruction de verrouillage dans sa propre fenêtre. Le premier va se bloquer, attendant que le verrou soit libéré, et le second sera exécuté immédiatement (et affichera les "données corrompues"). Ne pas oublier d'émettre

ROLLBACK 

lorsque vous avez terminé.

+0

+1 Pour attraper la distinction de (nolock) vs nolock - place sur en ce qui concerne l'alias. La distinction devrait être l'utilisation de "(nolock) vs avec (nolock)" plutôt que "nolock vs avec (nolock)" comme le montre la question - bonne prise – chadhoc

18

La liste des fonctionnalités dépréciées est à Deprecated Database Engine Features in SQL Server 2008:

  • Spécification NOLOCK ou READUNCOMMITTED dans la clause FROM d'un UPDATE ou DELETE .
  • Définition tableau conseils sans utiliser le mot-clé AVEC.
  • Indicateur de table HOLDLOCK sans parenthèse
  • Utilisation d'un espace comme séparateur entre les conseils de table.
  • L'application indirecte des indicateurs de table à l'invocation d'une fonction table multi-instruction (TVF) à travers une vue.

Ils sont tous dans la liste des fonctionnalités qui seront supprimés parfois après la prochaine version de SQL, ce qui signifie qu'ils vont probablement être pris en charge dans la version enxt que sous un niveau de compatibilité de la base inférieure.

Cela étant dit mon 2c sur la question sont en tant que tels:

  • Les deux from table nolock et from table with(nolock) ont tort. Si vous avez besoin de lectures sales, vous devez utiliser les niveaux transaction isolation appropriés: set transaction isolation level read uncommitted.De cette manière, le niveau d'islation utilisé est explicitement indiqué et contrôlé à partir d'un «bouton», au lieu d'être étalé dans la source et soumis à toutes les bizarreries des conseils de table (application indirecte via les vues et les TVF, etc.).
  • Les lectures sales sont une abon- dance. Ce qui est nécessaire, dans 99,99% des cas, est la réduction des conflits, pas la lecture des données non validées. La contention est réduite en écrivant des requêtes appropriées sur un schéma bien conçu et, si nécessaire, en déployant l'isolation d'instantané. La meilleure solution, qui permet de résoudre des œuvres sauver presque toujours quelques cas extrêmes, est enable read commited snapshot dans la base de données et de laisser le moteur fonctionner sa magie:

    ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
    ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON

Purgez alors des conseils de la sélectionne.

+1

+1 pour un couple de choses, la première fois que je remarqué la dépréciation de nolock dans le pour mise à jour/suppressions - très agréable. Bien que je ne sois pas totalement d'accord avec le fait que les lectures sales soient une abomination (il y a des scénarios où il peut être logique d'utiliser, même sur une approche optimiste de lecture), je suis d'accord que c'est trop utilisé, mal compris et , très peu de scénarios où cela a du sens et encore moins où l'utilisation est réellement comprise. – chadhoc

+0

Je suis d'accord que les lectures sales ont leur utilisation, mais disons que j'aime utiliser un effet dramatique pour souligner le message. –

+0

NOLOCK a été répertorié comme "Fonctionnalités non prises en charge dans la prochaine version de SQL Server" pour plusieurs versions de SQL Server. 2008, 2014 et 2016. –

0

Les deux sont syntaxiquement corrects. NOLOCK deviendra l'alias pour table1.

WITH (NOLOCK) est souvent utilisé comme un moyen magique d'accélérer les lectures de base de données, mais j'essaie d'éviter de l'utiliser autant que possible.

Le jeu de résultats peut contenir des lignes qui n'ont pas encore été validées et qui sont souvent annulées plus tard.

Une erreur ou un ensemble de résultats peut être vide, manquer des lignes ou afficher la même ligne plusieurs fois. Ceci est dû au fait que d'autres transactions déplacent des données en même temps que vous les lisez. READ COMMITTED ajoute un problème supplémentaire lorsque des données sont corrompues dans une seule colonne où plusieurs utilisateurs modifient la même cellule simultanément.

Il existe également d'autres effets secondaires qui ont pour effet de sacrifier l'augmentation de la vitesse que vous espériez obtenir en premier lieu.

Maintenant, vous savez, ne l'utilisez plus jamais.