Только некоторые вещи, которые всплыли: убедитесь, что вы не создаете подготовленные операторы в своих циклах. Это связано с некоторыми накладными расходами, но окупается после 3-го запроса или около того. На самом деле с большим списком параметров это может быть даже быстрее для одного запроса.
Что-то, что значительно ускоряет процесс, - это выполнение всех ваших запросов в одной (или нескольких крупных) транзакциях. Если это большие наборы данных, вы можете выполнить до 1000 запросов на транзакцию или что-то подобное. (Конечно, семантика вашей доменной модели должна учитывать это, но по моему опыту, это почти всегда так).
Количество запросов, которые вы можете объединить в одну транзакцию, в некоторой степени зависит от базы данных, поэтому могут потребоваться некоторые эксперименты и чтение.