CREATE TRIGGER занимает больше 30 минут на SQL Server 2005 - PullRequest
2 голосов
/ 23 октября 2008

В нашей действующей / производственной базе данных я пытаюсь добавить триггер к таблице, но безуспешно. Я пытался несколько раз, но это заняло более 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 триггеры создаются включенными по умолчанию. Можно ли создать отключенный по умолчанию триггер?

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

Ответы [ 5 ]

6 голосов
/ 23 октября 2008

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

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

4 голосов
/ 23 октября 2008

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

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

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

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

2 голосов
/ 02 июня 2009

Частью проблемы также может быть сам триггер. Может ли ваш триггер случайно обновить все строки таблицы? Существует большая разница между 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&disp=single&more=1&c=1&tb=1&pb=1#c1210

2 голосов
/ 23 октября 2008

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

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

0 голосов
/ 01 июня 2016

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...