Оператор DELETE зависает на SQL Server без видимой причины - PullRequest
9 голосов
/ 11 сентября 2008

Редактировать : Решено, был триггер с циклом на столе (читайте мой собственный ответ ниже).


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

DELETE FROM tablename WHERE pk = 12345

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

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

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

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

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

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

Попробовал DBCC DBREINDEX и ОБНОВЛЕНИЕ СТАТИСТИКИ на столе. Оба были завершены в разумные сроки.

К сожалению, в этой конкретной таблице очень много индексов. Это основная таблица в нашей системе с множеством столбцов и ссылок, как исходящих, так и входящих. Точное число - 48 индексов + кластерный индекс первичного ключа.

На что еще мы должны смотреть?

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

Ответы [ 3 ]

4 голосов
/ 11 сентября 2008

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

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

3 голосов
/ 11 сентября 2008

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

DBCC REINDEX

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

1 голос
/ 11 сентября 2008

Хорошо, это смущает.

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

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

Ну да ладно ...

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

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

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