Инструкция DELETE зависает на SQL Server без видимой причины


Edit : решено, на столе был триггер с петлей (читайте мой собственный ответ ниже).


У нас есть простой оператор delete, который выглядит следующим образом:

DELETE FROM tablename WHERE pk = 12345

Это просто висит, никакого тайм-аута, ничего.

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

В настоящее время нет другого пользователя, подключенного к базе данных.

Мы запустили DBCC CHECKDB против него, и он сообщает 0 ошибок.

Глядя на результаты sp_who и еще sp_lock пока запрос висит, я замечаю, что мой spid имеет множество замков PAG и KEY, а также случайный замок TAB.

Таблица содержит 1.777.621 строк, и да, pk является первичным ключом, поэтому это удаление одной строки на основе индекса. В таблице отсутствует сканирование. план выполнения, хотя я замечаю, что он содержит что-то, что говорит таблица Spool (нетерпеливый Spool), но говорит предполагаемое количество строк 1. Может ли это на самом деле быть скрытым сканированием таблицы? Он только говорит, что смотрит на столбец первичного ключа.

Попробовал DBCC DBREINDEX и обновить статистику по таблице. Оба завершены в разумные сроки.

К сожалению, в этой конкретной таблице имеется большое количество индексов. Это основная таблица в нашей системе, с большим количеством столбцов, и ссылки, как исходящие, так и входящие. Точное число-48 индексов + кластеризованный индекс первичного ключа. На что еще нам следует обратить внимание? Заметьте также, что эта таблица не имела этой проблемы раньше, эта проблема возникла неожиданно сегодня. У нас также есть много баз данных с одинаковыми настройками таблиц (копии клиентских баз данных), и они ведут себя так, как и ожидалось, именно это и является проблематичным.
3 8

3 ответа:

Одной недостающей информацией является количество индексов в таблице, из которой вы удаляете данные. Поскольку SQL Server использует первичный ключ в качестве указателя в каждом индексе, любое изменение первичного индекса требует обновления каждого индекса. Хотя, если мы не говорим о большом количестве, это не должно быть проблемой.

Я предполагаю, исходя из вашего описания, что это первичная таблица в базе данных, на которую ссылаются многие другие таблицы в связях FK. Это могло бы объяснить большое количество блокировок, так как он проверяет остальные таблицы на наличие ссылок. И, если вы включили каскадные удаления, это может привести к удалению в таблице a, требующему проверки нескольких таблиц в глубину.

Попробуйте воссоздать индекс в этой таблице и повторно создать статистику.

DBCC REINDEX

СТАТИСТИКА ОБНОВЛЕНИЙ

Ладно, это смущает.

Коллега добавил триггер к этой таблице некоторое время назад, и у триггера была ошибка. Хотя он исправил ошибку, триггер никогда не был воссоздан для этого стола.

Таким образом, сервер фактически ничего не делал, он просто делал это огромное количество раз.

Ну ладно...

Спасибо за глаза всем, кто читал это и размышлял над проблемой.

Я собираюсь принять ответ Йозефа, поскольку его ответ был самым близким, и косвенно thouched на проблеме с каскадными удалениями.