SQL DELETE занимает слишком много времени - PullRequest
0 голосов
/ 28 августа 2018

У меня есть Azure SQL сервер (стандартный уровень, S3) с таблицами. У меня есть конкретный запрос, который выполняется очень долго:

DELETE FROM MyTable WHERE ID=@ID

Эта таблица имеет 150K строк. Запрос на удаление занимает + -10 минут.

Я пытался понять, почему. Сначала проверьте, насколько быстро находится эта строка в запросе SELECT. Я бегу:

SELECT * FROM MyTable WHERE ID=@ID

Результат: менее 2 секунд.

Я читал об этой проблеме в этой теме . Я взял выбранный ответ и извлек из него контрольный список. Смотрите мои ответы внутри.

Контрольный список:

  • удаление большого количества записей - Этот запрос удаляет ровно 1 строку.
  • много индексов - MyTable имеет: 1 PK, 1 FK, 4 индекса и ничего больше. Поэтому я верю, что это не проблема.
  • отсутствующие индексы для внешних ключей в дочерних таблицах - Мой единственный FK имеет также INDEX для другой таблицы.
  • триггеров - без триггеров.
  • каскадное удаление (те десять родительских записей, которые вы удаляете, могут означать удаление миллионов дочерних записей) - Я попытался удалить строку, на которую ссылаются другие таблицы. Таким образом, каскадное удаление не должно ничего удалять на других таблицах.
  • Много внешних ключей для проверки - не уверен, что это значит. У меня есть только один FK, который указывает на очень маленькую таблицу (<10 строк + индекс). </li>
  • Журнал транзакций должен расти - Как проверить?
  • взаимоблокировки и блокировки - Как проверить?

У меня такое ощущение, что это как-то зависит от других таблиц, которые ссылаются на эту таблицу (MyTable для них FK). Поскольку у меня + -15 таблиц, я не знаю, как найти проблему.

Дополнительное наблюдение: Я нашел что-то интересное. Если вы выполняете удаление один за другим, первый вызов занимает много времени (как сообщалось выше), второй вызов выполняется быстрее и так далее. Если вы выполняете этот запрос несколько раз, он становится действительно быстрым (<3 секунды - это здорово). Через несколько часов - снова стало медленно. </p>

Вопросы:

  1. Что еще проверить?
  2. Можно ли выполнить запрос DELETE и профилировать его? Предположим, что table2 имеет FK до MyTable, а поиск строки @ID занимает много времени. Может быть, у меня может быть инструмент, который говорит: «99% времени выполнения тратится на table2
  3. Любые другие советы будут приветствоваться!

Спасибо!

1 Ответ

0 голосов
/ 29 августа 2018

Решил проблему.

Для этого я сделал:

  1. Вручную проверил все таблицы в базе данных и подтвердил, что они имеют индекс выше FK до MyTable. Я нашел 4 таблицы с отсутствующими индексами. Эти таблицы были довольно маленькими (<1K строк). Не уверен, насколько это было эффективно. </li>
  2. У меня был SP, который выполнялся довольно много раз. Этот SP выполнял транзакцию с блокировкой на одной из таблиц с FK до MyTable. Я снял замок. Аджиан, не уверен, насколько он эффективен, поскольку вышеупомянутый сенарио состоит в том, что в строке нет фактически ни одной строки FK в других таблицах.

Однако, теперь это работает как шарм! Время выполнения <1 секунда! </p>

...