Лучший подход к заданному вопросу - использовать чистый SQL, например:
update employees set
salary = salary * .9
Очень трудно представить, что нужно что-то делать с данными сотрудника, которые SQL не может обработать.
Если по какому-то причудливому замыслу вам действительно нужно было сделать что-то для данных типа сотрудника, чего SQL абсолютно не может сделать, то вы бы открыли курсор на наборе строк и провели итерацию по нему, производя обновление синхронно, так что вы делаете только один проход данных.
В псевдокоде:
cursor = forUpdate ("select for update * from employees")
while (cursor.next()) {
cursor.salary = cursor.salary * .9
}
Это самый простой и, вероятно, самый быстрый подход к исполнению.
-
Относительно регистрации
Это всего 2M строк, что является «небольшим» количеством, поэтому большинство БД может обрабатывать его за одну транзакцию. Однако, если нет, добавьте предложение where, например, where id between <start> and <end>
, к запросу, чтобы разделить процесс на регистрируемые суммы при использовании подхода сценария оболочки.
Если используется кодовый подход, большинство баз данных позволяют вам фиксировать, удерживая курсор открытым, поэтому просто фиксируйте каждые 10K строк или около того.
Относительно блокировки
Подобные аспекты ведения журнала. Все строки в таком запросе блокируются на время транзакции. Учитывая, что это займет так много времени, выбери тихое время для бега. Если это действительно важно, разберитесь, но поймите, что блокировка неизбежна.