CREATE TRIGGER занимает больше 30 минут на SQL Server 2005

StackOverflow https://stackoverflow.com/questions/230642

  •  04-07-2019
  •  | 
  •  

Вопрос

В нашей действующей / производственной базе данных я пытаюсь добавить триггер к таблице, но безуспешно. Я пытался несколько раз, но это заняло более 30 минут, чтобы завершить оператор создания триггера, и я отменил его.

Эта таблица часто читается / записывается несколькими разными процессами. Я отключил запланированные задания, которые обновляют таблицу, и пытался время от времени, когда в таблице меньше активности, но я не могу остановить все, что обращается к таблице.

Я не верю, что существует проблема с самим оператором создания триггера. Оператор создания триггера был успешным и быстрым в тестовой среде, и триггер работает правильно, когда строки вставляются / обновляются в таблицу. Хотя, когда я создал триггер в тестовой базе данных, в таблице не было нагрузки, и в ней было значительно меньше строк, что отличается от данных в рабочей / рабочей базе данных (100 против 13 000 000 +).

Вот оператор создания триггера, который я пытаюсь запустить

CREATE TRIGGER [OnItem_Updated] 
    ON  [Item]
   AFTER UPDATE
AS 
BEGIN
    SET NOCOUNT ON;

    IF update(State)
    BEGIN
        /* do some stuff including for each row updated call a stored 
          procedure that increments a value in table based on the 
          UserId of the updated row */
    END
END

Могут ли быть проблемы с созданием триггера для таблицы во время обновления строк или если в ней много строк?

В SQLServer триггеры создаются включенными по умолчанию. Можно ли создать отключенный по умолчанию триггер?

Есть еще идеи?

Это было полезно?

Решение

Возможно, проблема не в самой таблице, а в системных таблицах, которые необходимо обновить, чтобы создать триггер. Если вы используете какой-либо другой вид DDL как часть ваших обычных процессов, они могут его задержать.

Используйте sp_who, чтобы узнать, откуда идет блок, а затем исследуйте его.

Другие советы

Я полагаю, что триггер CREATE попытается заблокировать всю таблицу.

Если у вас много активности за этим столом, возможно, придется долго ждать, и вы можете создать тупик.

Для любых изменений схемы вы должны получить всю базу данных.

Это сказало, что заманчиво положить в "маленький" меняется с активными подключениями. Вы должны взглянуть на блокировки / соединения, чтобы увидеть, где происходит конфликт блокировок.

Странно. Триггер AFTER UPDATE не должен проверять существующие строки в таблице. Я полагаю, что вы не можете получить блокировку таблицы, чтобы добавить триггер.

Вы можете попробовать создать триггер, который в принципе ничего не делает. Если вы не можете создать это, тогда это проблема блокировки. Если вы можете, то вы можете отключить этот триггер, добавить нужный код в тело и включить его. (Я не верю, что вы можете отключить триггер во время создания.)

Частью проблемы также может быть сам триггер. Может ли ваш триггер случайно обновить все строки таблицы? Существует большая разница между 100 строками в тестовой базе данных и 13 000 000. Очень плохо разрабатывать код для такого небольшого набора, когда у вас такой большой набор данных, что вы не можете предсказать производительность. SQL, который отлично работает на 100 записей, может полностью заблокировать систему с миллионами на несколько часов. Вы действительно хотите знать это в dev, а не когда вы продвигаете prod.

Вызов хранимого процесса в триггере обычно очень плохой выбор. Это также означает, что вы должны циклически просматривать записи, что является еще худшим выбором в триггере. Триггеры должны иметь учетную запись alawys для множественного добавления / обновления или удаления записей. Если кто-то вставит 100 000 строк (что весьма вероятно, если у вас есть 13 000 000 записей), то циклический просмотр хранимого процесса на основе записей может занять несколько часов, заблокировать всю таблицу и заставить всех пользователей захотеть выследить разработчика и убить (или, по крайней мере, искалечить) его, потому что они не могут выполнить свою работу.

Я бы даже не подумал поставить этот триггер на prod, пока вы не протестируете набор записей, равный по размеру с prod.

Мой друг Деннис написал эту статью, которая иллюстрирует, почему тестирование небольшого объема информации при наличии большого объема информации может создать трудности в prd, которые вы не заметили в dev: http://blogs.lessthandot.com/index.php/DataMgmt/?blog=3&title=your-testbed-has-to-have-the-same-volume& дисп = одиночный & амп; более = 1 & амп; с = 1 & амп; Тв = 1 & амп; Pb = 1 # C1210

Запустите DISABLE TRIGGER имя триггера ON tablename перед изменением триггера, затем снова включите его с помощью ENABLE TRIGGER триггер ON ON tablename

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top