Если взять какие-либо данные одинаковой структуры и объёма, то сортировка, группировка и агрегация этих данных в Python будет на порядок медленнее, чем в СУБД. Даже если в Python эти данные будут располагаться в памяти. Но передача результата обработки данных от СУБД в Python код будет на два порядка дольше, чем обработка их в Python. Именно ввод/вывод - это самая медленная часть. Настолько медленная, что на её фоне всё остальное - несущественные издержки. Эту проблему и решает асинхронность, позволяя программе вместо простаивания выполнять какие-либо полезные действия в момент ожидания ввода/вывода. Но это работает только в том случае, если абсолютно весь код асинхронный. Если один вызов блокирующийся, асинхронность всей остальной цепочки вызовов бесполезна.
И не эффективнее ли будет стандартная многопроцессная парадигма работы postgres, когда на каждое подключение создаётся отдельный процесс.
Кроме того можно ведь обращаться к синхронной базе на psycopg2 через run_in_executor()
И то и другое подходит пока у вас не больше 50 rps. Во-первых, каждый поток потребляет ресурсы сервера. Во-вторых, запуск, остановка и синхронизация потоков приводят к дополнительным издержкам. Эти два пункта справедливы и для процессов, только сказанное можно смело умножать на тысячу.