Prisma: очень медленная вложенная запись при подключении к удаленной базе данных Postrgsql на AWS

#postgresql #nestjs #prisma

Вопрос:

Я пишу очень простой запрос с помощью prisma:

 async createContext(contextData: CreateContextDto): Promise<ContextRO> {
    const statements = contextData.body
      .split('n')
      .filter((statement) => statement !== '')
      .map((statement) => ({ content: statement }));
    const context = await this.prisma.context.create({
      data: {
        contextName: contextData.name,
        userId: contextData.user,
        statements: {
          create: statements,
        },
      },
      include: {
        statements: true,
      },
    });

    return { context };
 

С локальным PostgreSQL один и тот же запрос занимает около 4 секунд. При подключении к PostgreSQL на AWS это занимает до 90 секунд.

Есть какие-нибудь идеи, почему это занимает так много времени?

Пожалуйста, найдите пример репо, воспроизводящего эту проблему.

И вывод cli при запуске Prisma с ‘DEBUG=*’

ps. если я выполню тот же запрос с typeorm с PostgreSQL на aws, это займет 1-2 секунды, так что это не проблема с развертыванием. (проверьте ветвь «typeorm», чтобы увидеть сравнение)

Комментарии:

1. вы используете обещание , но вы не решили, что вернулись !

2. Не могли бы вы попробовать включить nApi и посмотреть, есть ли какие-либо изменения? Вы можете узнать, как это сделать для вашей версии prisma, здесь . Если это не решит проблему, не могли бы вы зарегистрировать свои события Prisma и указать, что происходит при выполнении запроса? Вы можете настроить переменную env export DEBUG="*" для этого, как описано в статье об отладке документов.

3. @TasinIshmam хм, я пытался использовать «debug=*», а также «debug=prisma*», но результат такой же, как я опубликовал в приведенной выше сути. Последнее сообщение от движка: «prisma:клиент:libraryEngine отправляет запрос, this.libraryStarted: true 13s`. Я не понимаю, как я получаю журналы вовремя для каждого шага. Я постараюсь разобраться в этом немного подробнее

4. Вы можете подумать о добавлении собственного журнала отладки, чтобы узнать, какие SQL-запросы на самом деле генерируются на основе вашего запроса Prisma и продолжительности запроса. Для этого вы можете подключить событие «запрос» в Prisma. Вот немного кода: prisma.$on<‘запрос’>(‘запрос’, (e: любой) =<‘запрос’>> { const msg = <‘запрос’>> nBegin query (Prisma): -----n Query: ${e.query}n Parameters:${e.params}n Duration: ${e.duration}msnEnd query (Prisma): -----n console.debug(msg); })

5. @OlegYarin Привет, мне очень жаль за это. Дайте мне посмотреть, могу ли я попросить кого-нибудь взглянуть!

Ответ №1:

Вы должны использовать createMany вместо create . create использует отдельную вставку под капотом для каждой вложенной записи. Если statement к одной записи подключено много s context , вы выполняете множество отдельных запросов к удаленной базе данных, что довольно медленно.

Что вы можете сделать, так это:

  1. Используется create для создания одной context записи без вложенных statement записей.
  2. Используйте отдельный createMany для statement записей, вручную указав contextId использование id , которое вы получили на шаге 1.

Вы также можете включить запросы 1 и 2 в транзакцию, если считаете, что это уместно.