Нет тут серебряной пули.
"Боюсь, что multithreading - прямой путь к проблемам с локами на таблицах и сложностям в отладке. " - это заблуждение.
В первую очередь можно определить:
1. Будут ли объёмы обрабатываемых данных расти с ходом времени + будет ли функционал становиться "тяжелее". Если да, здесь вилка:
1.1. Постараться сократить их объем на уровне архитектуры решения. Например, использовать какую-либо группировку позволяющую за раз обработать схожие записи.
1.2. Противоположность 1.1 - не создавать избыточные записи, валидировать наличие "похожих" и пропускать этап создания, как следствие обработки.
1.3. Изначально целиться в многопоток.
2. Какие записи определяют атомарность? Если способ получения записей прост, либо они не пересекается среди множества записей или не обновляются и ложатся на индексы (ну индесы можно исправить всегда, а простоту получения можно обеспечить дополнительными уровнями абстракции на уровне данных) - это критерии ЗА многопоточность.
PS Рекомендую использовать, в данном случае, принцип разработки KISS:
https://ru.wikipedia.org/wiki/KISS_(...86%D0%B8%D0%BF)
PS2 "Какие еще есть за и против, подводные камни, и на что надо обратить внимание?" На соответствие принципам разработки SOLID или GRASP + наличию модульных тестов. Это гарантии простого видоизменения функционала в случае возникновения такой необходимости.