Каков наилучший способ выполнить массовое обновление всех записей в большой таблице

#mysql #ruby-on-rails #ruby

#mysql #ruby-on-rails #ruby

Вопрос:

Каков наилучший способ выполнить массовое обновление всех записей в большой таблице в MySQL?

Во время процесса очистки мы обновляем все строки в таблице users, которая содержит 28 миллионов строк, чтобы замаскировать несколько столбцов. В настоящее время для выполнения задачи rake требуется около 2 часов, а срок действия сеанса AWS также составляет 2 часа. Если задача rake занимает больше времени, чем истечение сеанса, сборка завершится неудачно.

Из-за большого количества записей мы обновляем 25 тысяч строк одновременно, используя find_in_batches, а затем update_all в результатах. Мы переключаемся между каждой партией, отключаясь на 0,1 с, чтобы избежать перегрузки процессора.

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

Одним из вариантов может быть пакетирование по диапазонам идентификаторов, а не по точным размерам пакета. Итак, обновите между идентификатором 1-100000, затем 100001-200000 и так далее. Это позволяет избежать передачи больших наборов идентификаторов. Поскольку в идентификаторах будут пробелы, каждый пакет будет разного размера, но это может не быть проблемой.

Спасибо за ваш вклад.

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

1. Что было бы не так с простым старым добрым SQL-запросом для обновления всего сразу? Это должно значительно сократить время обновления.

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

Ответ №1:

Для таких больших обновлений накладные расходы на выборку записей и создание экземпляров объектов AR очень значительны (а также будет замедление из-за GC), самый быстрый способ выполнить — это написать необработанный SQL-запрос, который выполнит обновление (или использовать update_all для его построения, что очень похоже, но позволяет использовать области / объединения по отношениям).