" Lock Escalation " est la façon dont SQL gère le verrouillage pour les mises à jour importantes. Lorsque SQL va changer beaucoup de lignes, il est plus efficace pour le moteur de base de données de prendre moins de verrous plus grands (par exemple, une table entière) au lieu de verrouiller beaucoup de petits éléments (par exemple, des verrous de lignes).
Mais cela peut être problématique lorsque vous avez une table énorme, car le fait de verrouiller la table entière peut verrouiller d'autres requêtes pendant une longue période. C'est le compromis: de nombreux verrous de petite granularité sont plus lents que moins (ou un) verrous à gros grain, et le fait d'avoir plusieurs requêtes verrouillant différentes parties d'une table crée la possibilité d'un blocage si un processus en attend un autre.
Il existe une option au niveau de la table,, LOCK_ESCALATION
nouvelle dans SQL 2008, qui permet de contrôler l'escalade des verrous. La valeur par défaut, «TABLE», permet aux verrous de remonter jusqu'au niveau de la table. DISABLE empêche l'escalade des verrous vers la table entière dans la plupart des cas. AUTO autorise les verrous de table sauf si la table est partitionnée, auquel cas les verrous ne sont constitués qu'au niveau de la partition. Voir ce billet de blog pour plus d'informations.
Je soupçonne que l'EDI ajoute ce paramètre lors de la recréation d'une table car TABLE est la valeur par défaut dans SQL 2008. Notez que LOCK_ESCALATION n'est pas pris en charge dans SQL 2005, vous devrez donc le supprimer si vous essayez d'exécuter le script sur un Instance de 2005. De plus, puisque TABLE est la valeur par défaut, vous pouvez supprimer cette ligne en toute sécurité lors de la réexécution de votre script.
Notez également que, dans SQL 2005 avant que ce paramètre soit présent, tous les verrous pouvaient escalader au niveau de la table - en d'autres termes, "TABLE" était le seul paramètre sur SQL 2005.
CREATE TABLE
car la table n'existe pas encore donc il n'y a rien à verrouiller.ALTER TABLE
instructions distinctes . D'abordALTER TABLE ADD column
, puisGO
, puis ensuite , puisALTER TABLE SET LOCK_ESCALATION=TABLE
ensuiteGO
. Donc,LOCK_ESCALATION
est défini après l'ajout de la colonne. Quel est l'intérêt de le régler après coup? Ces deuxALTER TABLE
instructions sont encapsulées dans une transaction, mais la colonne est toujours ajoutée avant laLOCK_ESCALATION
définition de. Je pense que je vais creuser un peu plus et écrire une autre réponse.Vous pouvez vérifier si vous devez inclure l'instruction LOCK_ESCALATION dans votre script en comparant cette valeur avant et après l'exécution de la partie principale de votre script:
Dans mon cas, modifier la table pour supprimer ou ajouter une contrainte ne semble pas modifier cette valeur.
la source
La réponse de Justin Grant explique ce que fait le
LOCK_ESCALATION
paramètre en général, mais manque un détail important et n'explique pas pourquoi SSMS génère le code qui le définit. Surtout, il semble très étrange que leLOCK_ESCALATION
soit défini comme dernière instruction dans le script.J'ai fait quelques tests et voici ma compréhension de ce qui se passe ici.
Version courte
L'
ALTER TABLE
instruction qui ajoute, supprime ou modifie une colonne prend implicitement un verrou de modification de schéma (SCH-M) sur la table, ce qui n'a rien à voir avec leLOCK_ESCALATION
réglage d'une table.LOCK_ESCALATION
affecte le comportement de verrouillage dans les déclarations DML (INSERT
,UPDATE
,DELETE
, etc.), et non pas dans les instructions DDL (ALTER
). Le verrou SCH-M est toujours un verrou de tout l'objet de base de données, tableau dans cet exemple.C'est probablement de là que vient la confusion.
SSMS ajoute l'
ALTER TABLE <TableName> SET (LOCK_ESCALATION = ...)
instruction à son script dans tous les cas, même lorsqu'elle n'est pas nécessaire. Dans les cas où cette instruction est nécessaire, elle est ajoutée pour conserver le paramètre actuel de la table, pas pour verrouiller la table d'une manière spécifique lors de la modification du schéma de table qui se produit dans ce script.En d'autres termes, la table est verrouillée avec le verrou SCH-M sur la première
ALTER TABLE ALTER COLUMN
instruction pendant que tout le travail de modification du schéma de table est effectué. La dernièreALTER TABLE SET LOCK_ESCALATION
déclaration ne l'affecte pas. Cela n'affecte que les futures instructions DML (INSERT
,UPDATE
,DELETE
, etc.) pour cette table.À première vue, il semble que
SET LOCK_ESCALATION = TABLE
quelque chose à voir avec le fait que nous changeons toute la table (nous modifions son schéma ici), mais c'est trompeur.Version longue
Lors de la modification de la table dans certains cas, SSMS génère un script qui recrée la table entière et dans certains cas plus simples (comme l'ajout ou la suppression d'une colonne), le script ne recrée pas la table.
Prenons cet exemple de tableau comme exemple:
Chaque table a un
LOCK_ESCALATION
paramètre, qui est définiTABLE
par défaut. Changeons-le ici:Maintenant, si j'essaie de changer le
Col1
type dans le concepteur de table SSMS, SSMS génère un script qui recrée la table entière:Vous pouvez voir ci-dessus qu'il définit
LOCK_ESCALATION
pour la table nouvellement créée. SSMS le fait pour conserver le paramètre actuel de la table. SSMS génère cette ligne, même si la valeur actuelle du paramètre est laTABLE
valeur par défaut . Juste pour être sûr et explicite et éviter d'éventuels problèmes futurs si, à l'avenir, cette valeur par défaut change, je suppose. C'est logique.Dans cet exemple, il est vraiment nécessaire de générer l'
SET LOCK_ESCALATION
instruction, car la table est créée à nouveau et son paramètre doit être conservé.Si j'essaie d'apporter une modification simple à la table à l'aide du concepteur de table SSMS, par exemple en ajoutant une nouvelle colonne, SSMS génère un script qui ne recrée pas la table:
Comme vous pouvez le voir, il ajoute toujours l'
ALTER TABLE SET LOCK_ESCALATION
instruction, même si dans ce cas, ce n'est pas du tout nécessaire. Le premierALTER TABLE ... ADD
ne modifie pas le paramètre actuel. Je suppose que les développeurs SSMS ont décidé qu'il ne valait pas la peine d'essayer de déterminer dans quels cas celaALTER TABLE SET LOCK_ESCALATION
déclaration est redondante et de la générer toujours, juste pour être sûr. Il n'y a aucun mal à ajouter cette déclaration à chaque fois.Une fois de plus, le
LOCK_ESCALATION
paramètre à l' échelle de la table n'est pas pertinent alors que le schéma de la table change via l'ALTER TABLE
instruction.LOCK_ESCALATION
paramètre affecte uniquement le comportement de verrouillage des instructions DML, commeUPDATE
.Enfin, une citation de
ALTER TABLE
, souligne la mienne:la source