Mit " Eskalation sperren" behandelt SQL das Sperren für große Updates. Wenn SQL viele Zeilen ändern wird, ist es für das Datenbankmodul effizienter, weniger größere Sperren (z. B. die gesamte Tabelle) zu verwenden, anstatt viele kleinere Dinge (z. B. Zeilensperren) zu sperren.
Dies kann jedoch problematisch sein, wenn Sie eine große Tabelle haben, da eine Sperre für die gesamte Tabelle andere Abfragen für lange Zeit sperren kann. Das ist der Kompromiss: Viele Sperren mit kleiner Granularität sind langsamer als weniger (oder eine) grobkörnige Sperren. Wenn mehrere Abfragen verschiedene Teile einer Tabelle sperren, besteht die Möglichkeit eines Deadlocks, wenn ein Prozess auf einen anderen wartet.
Es gibt eine LOCK_ESCALATION
neue Option auf Tabellenebene in SQL 2008, mit der die Eskalation von Sperren gesteuert werden kann. Die Standardeinstellung "TABLE" ermöglicht, dass Sperren bis zur Tabellenebene eskalieren. DISABLE verhindert in den meisten Fällen eine Eskalation der Sperre für die gesamte Tabelle. AUTO erlaubt Tabellensperren, außer wenn die Tabelle partitioniert ist. In diesem Fall werden Sperren nur bis zur Partitionsebene vorgenommen. Weitere Informationen finden Sie in diesem Blogbeitrag .
Ich vermute, dass die IDE diese Einstellung beim erneuten Erstellen einer Tabelle hinzufügt, da TABLE in SQL 2008 die Standardeinstellung ist. Beachten Sie, dass LOCK_ESCALATION in SQL 2005 nicht unterstützt wird. Sie müssen sie daher entfernen, wenn Sie versuchen, das Skript auf einem auszuführen Instanz 2005. Da TABLE die Standardeinstellung ist, können Sie diese Zeile auch sicher entfernen, wenn Sie Ihr Skript erneut ausführen.
Beachten Sie auch, dass in SQL 2005, bevor diese Einstellung vorhanden war, alle Sperren auf Tabellenebene eskalieren konnten. Mit anderen Worten, "TABLE" war die einzige Einstellung in SQL 2005.
CREATE TABLE
da die Tabelle noch nicht vorhanden ist und daher nichts gesperrt werden muss.ALTER TABLE
Anweisungen. ErstALTER TABLE ADD column
dannGO
, dann zweitensALTER TABLE SET LOCK_ESCALATION=TABLE
, dann zweitensGO
. WirdLOCK_ESCALATION
also festgelegt, nachdem die Spalte hinzugefügt wurde. Was bringt es, es nachträglich einzustellen? Diese beidenALTER TABLE
Anweisungen werden in eine Transaktion eingeschlossen, aber die Spalte wird noch hinzugefügt, bevor dieLOCK_ESCALATION
festgelegt wird. Ich denke, ich werde ein bisschen weiter graben und eine andere Antwort schreiben.Sie können überprüfen, ob Sie die Anweisung LOCK_ESCALATION in Ihr Skript aufnehmen müssen, indem Sie diesen Wert vor und nach dem Ausführen des Hauptteils Ihres Skripts vergleichen:
In meinem Fall scheint das Ändern der Tabelle zum Löschen oder Hinzufügen einer Einschränkung diesen Wert nicht zu ändern.
quelle
Die Antwort von Justin Grant erklärt, was die
LOCK_ESCALATION
Einstellung im Allgemeinen bewirkt, übersieht jedoch ein wichtiges Detail und erklärt nicht, warum SSMS den Code generiert, der sie festlegt. Insbesondere sieht es sehr seltsam aus, dass dasLOCK_ESCALATION
als letzte Anweisung im Skript gesetzt ist.Ich habe nur wenige Tests durchgeführt und hier ist mein Verständnis dafür, was hier passiert.
Kurzfassung
Die
ALTER TABLE
Anweisung, die implizit eine Spalte hinzufügt, löscht oder ändert, erfordert eine SCH-M-Sperre (Schema Modify) für die Tabelle, die nichts mit derLOCK_ESCALATION
Einstellung einer Tabelle zu tun hat .LOCK_ESCALATION
wirkt sich das Verhalten während der DML - Anweisungen Sperren (INSERT
,UPDATE
,DELETE
, etc.), nicht während der DDL - Anweisungen (ALTER
). Die SCH-M-Sperre ist immer eine Sperre des gesamten Datenbankobjekts, in diesem Beispiel der Tabelle.Dies ist wahrscheinlich, woher die Verwirrung kommt.
SSMS fügt die
ALTER TABLE <TableName> SET (LOCK_ESCALATION = ...)
Anweisung in allen Fällen zu seinem Skript hinzu , auch wenn sie nicht benötigt wird. In den Fällen , wenn diese Anweisung benötigt wird, wird es hinzugefügt , um die aktuelle Einstellung der Tabelle zu erhalten, nicht um die Tabelle zu sperren in irgendeiner bestimmten Weise während der Änderung der Tabelle Schema , das in diesem Skript passiert.Mit anderen Worten, die Tabelle wird bei der ersten
ALTER TABLE ALTER COLUMN
Anweisung mit der SCH-M-Sperre gesperrt, während die gesamte Arbeit zum Ändern des Tabellenschemas erledigt ist. Die letzteALTER TABLE SET LOCK_ESCALATION
Aussage hat keinen Einfluss darauf. Es wirkt sich nur Aussagen über zukünftige DML (INSERT
,UPDATE
,DELETE
, etc.) für diese Tabelle.Auf den ersten Blick sieht es so aus, als hätte
SET LOCK_ESCALATION = TABLE
es etwas damit zu tun, dass wir die gesamte Tabelle ändern (wir ändern hier ihr Schema), aber es ist irreführend.Lange Version
Wenn Sie die Tabelle in einigen Fällen ändern, generiert SSMS ein Skript, das die gesamte Tabelle neu erstellt, und in einigen einfacheren Fällen (z. B. Hinzufügen oder Löschen einer Spalte) erstellt das Skript die Tabelle nicht neu.
Nehmen wir diese Beispieltabelle als Beispiel:
Jede Tabelle verfügt über eine
LOCK_ESCALATION
Einstellung, dieTABLE
standardmäßig festgelegt ist. Lassen Sie es uns hier ändern:Wenn ich nun versuche, den
Col1
Typ im SSMS-Tabellen-Designer zu ändern, generiert SSMS ein Skript, das die gesamte Tabelle neu erstellt:Sie können oben sehen, dass es
LOCK_ESCALATION
für die neu erstellte Tabelle festgelegt wird. SSMS tut dies, um die aktuelle Einstellung der Tabelle beizubehalten. SSMS generiert diese Zeile, auch wenn der aktuelle Wert der Einstellung der StandardwertTABLE
ist. Nur um sicher und explizit zu sein und mögliche zukünftige Probleme zu vermeiden, wenn sich diese Standardeinstellung in Zukunft ändert, denke ich. Das macht Sinn.In diesem Beispiel ist es wirklich erforderlich, die
SET LOCK_ESCALATION
Anweisung zu generieren , da die Tabelle neu erstellt wird und ihre Einstellung beibehalten werden muss.Wenn ich versuche, mithilfe des SSMS-Tabellen-Designers eine einfache Änderung an der Tabelle vorzunehmen, z. B. eine neue Spalte hinzuzufügen, generiert SSMS ein Skript, das die Tabelle nicht neu erstellt:
Wie Sie sehen können, wird die
ALTER TABLE SET LOCK_ESCALATION
Anweisung trotzdem hinzugefügt , obwohl sie in diesem Fall überhaupt nicht benötigt wird. Die ersteALTER TABLE ... ADD
ändert die aktuelle Einstellung nicht. Ich denke, SSMS-Entwickler haben entschieden, dass es sich nicht lohnt, festzustellen, in welchen Fällen dieseALTER TABLE SET LOCK_ESCALATION
Anweisung redundant ist, und sie immer zu generieren, nur um sicher zu gehen. Es schadet nicht, diese Aussage jedes Mal hinzuzufügen.Auch hier ist die tabellenweite
LOCK_ESCALATION
Einstellung irrelevant, während sich das Tabellenschema über dieALTER TABLE
Anweisung ändert .LOCK_ESCALATION
Die Einstellung wirkt sich nur auf das Sperrverhalten von DML-Anweisungen aus, zUPDATE
.Zum Schluss ein Zitat aus
ALTER TABLE
, betonen Sie meins:quelle