При выполнении этих операций вы хотите, чтобы пользователь дождался их окончания? Или вы можете запустить эту задачу в фоновом режиме? Может быть, даже ночью во время какой-то запланированной обработки? Если последнее верно, вы можете придерживаться своего подхода и просто выполнить все свои миллионы обновлений, просто убедитесь, что вы не заставляете пользователя ждать завершения операции. В противном случае вам действительно нужно продумать способ переноса всей логики обновления в базу данных.
Таким образом, в зависимости от требований, варианты будут:
1) Запустите отдельный поток (или даже несколько потоков) для выполнения обновлений, в то время как основной поток вернет пользователю что-то вроде «Длительная операция выполняется. Пожалуйста, вернитесь на эту страницу позже, чтобы увидеть ее состояние»
2) запускать обновления ночью в отдельном процессе
3) Реорганизовать проект так, чтобы вы могли позволить себе выполнять обновления в базе данных.
UPDATE
Я вижу, как вы постоянно говорите, что не можете перенести логику обновления в базу данных. Если вы не несете ответственности за архитектуру проекта, можете ли вы повлиять на управление, чтобы реорганизовать весь материал? Похоже, плохая архитектура, если такие операции необходимы.