« Lock Escalation » - это то, как SQL обрабатывает блокировку для больших обновлений. Когда SQL собирается изменить много строк, для механизма базы данных более эффективно брать меньше больших блокировок (например, всей таблицы) вместо блокирования множества более мелких вещей (например, блокировок строк).
Но это может быть проблематично, если у вас огромная таблица, потому что блокировка всей таблицы может на долгое время блокировать другие запросы. Это компромисс: многие блокировки с малой гранулярностью работают медленнее, чем меньшее количество (или одна) грубых блокировок, а наличие нескольких запросов, блокирующих разные части таблицы, создает возможность тупиковой блокировки, если один процесс ожидает другого.
В LOCK_ESCALATION
SQL 2008 есть новая опция уровня таблицы , которая позволяет контролировать эскалацию блокировки. По умолчанию "TABLE" позволяет блокировкам увеличиваться до уровня таблицы. DISABLE предотвращает увеличение блокировки всей таблицы в большинстве случаев. AUTO разрешает блокировки таблиц, за исключением случаев, когда таблица секционирована, и в этом случае блокировки создаются только до уровня раздела. Смотрите этот пост в блоге для получения дополнительной информации.
Я подозреваю, что IDE добавляет этот параметр при повторном создании таблицы, потому что TABLE является значением по умолчанию в SQL 2008. Обратите внимание, что LOCK_ESCALATION не поддерживается в SQL 2005, поэтому вам придется удалить его, если вы пытаетесь запустить скрипт на 2005 год Кроме того, поскольку TABLE используется по умолчанию, вы можете безопасно удалить эту строку при повторном запуске сценария.
Также обратите внимание, что в SQL 2005 до появления этого параметра все блокировки могли повышаться до уровня таблицы - другими словами, «TABLE» был единственным параметром в SQL 2005.
CREATE TABLE
потому что таблица еще не существует, поэтому нечего блокировать.ALTER TABLE
оператора. СначалаALTER TABLE ADD column
, потомGO
, потом второйALTER TABLE SET LOCK_ESCALATION=TABLE
, потом второйGO
. Итак,LOCK_ESCALATION
устанавливается после добавления столбца. Какой смысл устанавливать это после факта? Эти дваALTER TABLE
оператора заключены в транзакцию, но столбец все еще добавляется до того,LOCK_ESCALATION
как он установлен. Я думаю, что я буду копать немного дальше и напишу другой ответ.Вы можете проверить, нужно ли включать оператор LOCK_ESCALATION в ваш скрипт, сравнив это значение до и после запуска основной части вашего скрипта:
В моем случае изменение таблицы для удаления или добавления ограничения, похоже, не изменяет это значение.
источник
Ответ Джастина Гранта объясняет, что
LOCK_ESCALATION
делает настройка в целом, но пропускает одну важную деталь и не объясняет, почему SSMS генерирует код, который ее устанавливает. Особенно странно выглядит то, чтоLOCK_ESCALATION
в сценарии это последнее утверждение.Я сделал несколько тестов, и вот мое понимание того, что здесь происходит.
Укороченная версия
ALTER TABLE
Утверждение , которое добавляет, удаляет или изменяет столбец неявно принимает схему изменения (SCH-M) блокировки таблицы, которая не имеет ничего общего сLOCK_ESCALATION
установкой стола.LOCK_ESCALATION
влияет поведение блокировки во время заявлений DML (INSERT
,UPDATE
,DELETE
и т.д.), а не во время заявлений DDL (ALTER
). Блокировка SCH-M всегда является блокировкой всего объекта базы данных, таблица в этом примере.Это, вероятно, откуда путаница.
SSMS добавляет
ALTER TABLE <TableName> SET (LOCK_ESCALATION = ...)
оператор в свой сценарий во всех случаях, даже если он не нужен. В тех случаях, когда этот оператор необходим, он добавляется для сохранения текущего параметра таблицы, а не для блокировки таблицы каким-либо особым образом во время изменения схемы таблицы, которое происходит в этом сценарии.Другими словами, таблица будет заблокирована с замком SCH-M на первом
ALTER TABLE ALTER COLUMN
заявлении в то время как вся работа изменения схемы таблицы делается. ПоследнееALTER TABLE SET LOCK_ESCALATION
утверждение не влияет на это. Это влияет только на заявления будущего DML (INSERT
,UPDATE
,DELETE
и т.д.) для этой таблицы.На первый взгляд это выглядит так, как будто
SET LOCK_ESCALATION = TABLE
имеет отношение к тому факту, что мы меняем всю таблицу (здесь мы меняем ее схему), но это вводит в заблуждение.Длинная версия
При изменении таблицы в некоторых случаях SSMS генерирует сценарий, который заново создает всю таблицу, а в некоторых более простых случаях (например, добавление или удаление столбца) сценарий не создает заново таблицу.
Давайте возьмем этот пример таблицы в качестве примера:
Каждая таблица имеет
LOCK_ESCALATION
настройку, которая установленаTABLE
по умолчанию. Давайте изменим это здесь:Теперь, если я пытаюсь изменить
Col1
тип в конструкторе таблиц SSMS, SSMS генерирует скрипт, который заново создает всю таблицу:Вы можете видеть выше, что он устанавливает
LOCK_ESCALATION
для вновь созданной таблицы. SSMS делает это, чтобы сохранить текущие настройки таблицы. SSMS генерирует эту строку, даже если текущее значение параметра являетсяTABLE
значением по умолчанию . Я полагаю, просто для того, чтобы быть точным и понятным и предотвратить возможные будущие проблемы, если в будущем это значение по умолчанию изменится. Это имеет смысл.В этом примере действительно необходимо сгенерировать
SET LOCK_ESCALATION
оператор, потому что таблица создается заново, и ее настройки должны быть сохранены.Если я попытаюсь внести простое изменение в таблицу с помощью конструктора таблиц SSMS, например добавить новый столбец, то SSMS создаст сценарий, который не создает таблицу заново:
Как видите, он по-прежнему добавляет
ALTER TABLE SET LOCK_ESCALATION
оператор, хотя в этом случае он вообще не нужен. ПервыйALTER TABLE ... ADD
не меняет текущие настройки. Я предполагаю, что разработчики SSMS решили, что не стоит пытаться определить, в каких случаях этоALTER TABLE SET LOCK_ESCALATION
утверждение является избыточным, и генерировать его всегда, просто чтобы быть в безопасности. Нет никакого вреда в добавлении этого утверждения каждый раз.Еще раз,
LOCK_ESCALATION
настройка всей таблицы не имеет значения, в то время как схема таблицы изменяется с помощьюALTER TABLE
оператора.LOCK_ESCALATION
настройка влияет только на поведение блокировки операторов DML, напримерUPDATE
.Напоследок приведу цитату
ALTER TABLE
, подчеркну мою:источник