SQL Server - низкая производительность удаления ПК - PullRequest
4 голосов
/ 21 октября 2010

У меня есть таблица в SQL Server 2008 R2, состоящая примерно из 400 строк (почти ничего) - она ​​имеет кластеризованный индекс по первичному ключу (который является идентификатором). Ссылка на таблицу осуществляется через ссылочную целостность (без каскадного удаления или обновления) примерно 13 другими таблицами.

Вставки / Обновления / Получение почти мгновенные - мы говорим доли секунды (как и следовало ожидать). Однако удаление с использованием PK занимает 3 минуты, и я никогда не видел его быстрее, чем 1,5 минуты:

DELETE FROM [TABLE] WHERE [TABLE].[PK_WITH_CLUSTERED_INDEX] = 1

Индекс был сильно фрагментирован - 90%. Я перестроил и реорганизовал этот индекс (вместе с остальными в этой таблице), но я не могу получить его ниже 50%.

Кроме того, я выполнил резервное копирование / восстановление базы данных на своем локальном ПК, и у меня нет проблем с удалением - менее секунды.

Единственное, что я не сделал, это полностью удалил кластеризованный индекс и заново его добавил. Это само по себе является проблемой, поскольку SQL Server не позволяет отбрасывать индекс PK, если на него ссылаются другие таблицы.

Есть идеи?

Обновление

Я должен был включить это в свой оригинальный пост. План выполнения возлагает вину на удаление кластеризованного индекса - 70%. Из 13 таблиц, которые ссылаются на эту таблицу, план выполнения говорит, что ни одна из них не превышает 3% общего запроса - почти все попадания в поиски индекса.

Ответы [ 4 ]

4 голосов
/ 21 октября 2010

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

1 голос
/ 26 октября 2010

Ну, у меня есть ответ ...

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

Я решил сделать следующее:

  1. Добавить временный уникальный индекс (поэтому SQL Сервер позволит мне удалить кластерный индекс)
  2. Удалить кластерный индекс.
  3. Повторно добавить кластерный индекс.
  4. Удалять временный уникальный индекс.

По сути, я стер и снова добавил кластерный индекс. Единственное, что я могу от этого извлечь, это то, что, возможно, часть индекса или место его физического хранения было «повреждено» (я использую этот термин свободно).

0 голосов
/ 21 октября 2010

Еще одна мысль, есть ли на столе триггер удаления? Может ли это быть причиной проблемы?

0 голосов
/ 21 октября 2010

Возможно, таблица заблокирована другим трудоемким процессом в производстве.

...