MS SQL: лучший способ удаления строк из огромной таблицы

#sql #sql-server-2008 #database-optimization

#sql #sql-server-2008 #оптимизация базы данных

Вопрос:

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

Проблема в том, что когда мы пытаемся удалить записи, это занимает много времени. Теперь мы выполнили следующие проверки для устранения неполадок, чтобы увидеть любые возможности, почему это занимает так много времени 1) Таблица индексируется 2) Нет неиндексированных внешних ключей 3) Нет триггеров, выполняющих дополнительную работу в фоновом режиме при удалении

Кто-нибудь из вас когда-нибудь сталкивался с подобным сценарием? Какой наилучшей процедуре следует следовать при выполнении чего-то подобного? И есть ли какие-либо инструменты, которые могут помочь?

Я ценю вашу помощь!

Комментарии:

1. Вы пробовали удалять с шагом с ограничениями?

2. Журнал транзакций находится на собственном диске? Имеет ли он достаточный размер или тратит много времени на автоматическое увеличение? Вам нужно беспокоиться о блокировке одновременных запросов? Рассматривали ли вы возможность вставки 10% для сохранения в новую таблицу, а затем переименования вместо удаления и повторной вставки 90%

3. Покажите нам свою инструкцию delete, и мы сможем ее диагностировать?

4. Да, именно так я продолжаю, и это все равно занимает вечность.

5. Журнал транзакций находится на другом диске, и да, он быстро автоматически растет не только из-за этой таблицы, но и из-за других. Но у нас есть части нашей системы, которые замедляются, особенно из-за этой таблицы [X], так что это наша главная проблема. Блокировка параллельных запросов — это то, чего мы не хотим делать, так как у нас есть записи, вставляемые в секунду в таблицу [X]. Поэтому, если мы блокируем, мы останавливаем активность клиентов. Давайте просто скажем, что сейчас об этом не может быть и речи. По той же причине мы не можем переместить только 10%, поскольку нам нужно, чтобы эта таблица была постоянно активной.

Ответ №1:

Опции

  • Почему бы не перенести 10% в новую таблицу?
  • Пакетное удаление / вставка не в транзакцию (см. Ниже)
  • Таблица разделов (она же позволяет движку справиться с этим)

Для заполнения архивной таблицы

 SELECT 'starting' -- sets @@ROWCOUNT
WHILE @@ROWCOUNT <> 0
BEGIN
    DELETE TOP (50000) dbo.Mytable
    OUTPUT DELETED.* INTO ArchiveTable 
    WHERE SomeCol < <Afilter>

    -- maybe CHECKPOINT

    WAIT FOR DELAY ...
END
  

Комментарии:

1. Итак, вы предлагаете мне удалять пакеты, пока не будут выполнены критерии? Критерием является, например, диапазон дат?

2. Здесь, например, «afilter» — это фильтр для «строк старше 6 месяцев». Критерии для «архивирования» данных зависят от вас

Ответ №2:

Вы должны пойти на разделение вашей базы данных / таблицы.

Комментарии:

1. Я согласен с Kangkan — создайте 2 раздела -> используемые и неиспользуемые данные. Тогда удаление означает, что вы переключаете неиспользуемый раздел на другую таблицу и удаляете таблицу.