Страницы

Поиск по вопросам

вторник, 7 мая 2019 г.

Как удалить много записей из базы данных [закрыт]

Простое удаление работает очень долго (около 40 секунд из одной таблицы, в которой примерно 1,5 миллиона записей), нужно сделать быстрее (нужно удалить все данные пользователя). База MSSQL.


Ответ

Если нужно удалить ВСЕ записи из некоторой таблицы, используйте TRUNCATE, предварительно удалив внешние ключи, которые ссылаются на таблицу. Это самый быстрый способ. Он, в частности, игнорирует триггеры.
Если просто большое количество, то нужно удалять пачками. Оптимизировал я job, который удалял устаревшие данные, порядка ~100млн. строк в неделю. запускался на выходных. Опытным путём пришёл к выводу, что быстрее всего строки удаляется пачками по 100-500 штук.
Создаём временную табличку с ID'ами записей которые будем удалять. Пишем туда 100-500 ID'ов. и вызываем:
DELETE T2 FROM #Table T1 INNER LOOP JOIN Table T2 ON T1.ID = T2.ID
Здесь нужен именно LOOP. Хотя сервер скорее всего и без хинтов догадается. Вместо ID таблицы Table, может быть любой уникальный ключ. В случае, если ключ кластерный, то в таблицу #Table желательно вставлять ID'ы пачек строк, которые записаны в Table "рядом".
Если целиком пачку удалить не удалось, вызываем удаление по одной записи и логируем результаты.(ну я так делал:)) потом утром анализируем.
UPD: по поводу быстрого поиска удаляемых записей. Стоит создать индекс по UserId и посмотреть станет лучше или нет.
UPD: чуть-чуть про то, почему именно пачками.
Удаление по одной записи - это N транзакций. Выполняется довольно медленно... Таким был job до того, как я начал его оптимизировать. Пытаться удалить одним DML оператором ~1млн строк тоже плохо. Т.к. сама транзакция становится очень большой и рискуем получить нехватку памяти. Да и выполняется это долго.
В итоге задавая размер пачки, я к каждой таблице подобрал оптимальное число одновременно удаляемых записей. Начальник был доволен(с) :)

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

Отправить комментарий