@beduin01

Как понять в какой момент тормозит БД?

Есть БД PostgreSQL. В нее пишутся результаты парсинга файлов.
Каждый экземпляр парсера формирует SQL INSERT и выплевывает его в микросервис. Микросервис пишет результат в БД.

Проблема в том, что пишется все очень медленно и по мере роста БД скорость записи в нее падает (уже около 5 млн строк).

Из индексов - стоит только индекс на главном идентификаторе записи MyID.

В начале я думал, что у меня все тормозит т.к. при каждой вставке перестраивается индекс. Но потом взял один SQL INSERT и скормил его в SQL чтобы посмотреть за сколько он вставится.

Он отработал за 23 миллисекунды. Т.е. явно затык не в этом.

А в чем понять не могу. Были мысли что может на стороне микросервиса тормозить, но там вроде бы логика предельно простая. Вставить транзакцию. Если не вставилась, то откатить и удалить MyID и вставить заново. Случаи дубликатов крайне редки, так что тормозит видимо не из-за них.

Вот если что код:
spoiler
Future<dynamic> sqlInsert(Map body) async {
  bool isDataWasInserted = false; // т.к. идет несколько попыток нам нужно внизу знать что возвращать

  try {
      print("Trying to insert data");
      print("sql: ${body['sql']}");
      // данные прилетают как запросы через точку-запятую

      await connection.transaction( (ctx) async {
        for (var s in body['sql']) {
              await ctx.query(s); 
            }  
            isDataWasInserted = true;
            print("INSERT SUCCESS\n");
        });

    }
    on PostgreSQLException catch(e)
    {
        print("FIRST INSERT FAILED: ${e.message} ");
        await connection.cancelTransaction();
       
       try {
            print("There is some duplicates. Removing them");
            await connection.transaction( (ctx) async {
              for (var s in body['sql-remove']) {
                    print(s);
                    await ctx.query(s); 
                }  
            });

          // новая попытка вставить
          try {
            await connection.transaction( (ctx) async {
                for (var s in body['sql']) {
                      await ctx.query(s);  
                    }  
                print("INSERT2 SUCCESS");
                  isDataWasInserted = true;
                }); 

            } on PostgreSQLException catch(e) {
                  print("SECOND INSERT WAS FAILED ${e.message}");
                  await connection.cancelTransaction();
                  writeLog("SECOND INSERT WAS FAILED ", e.message); // нельзя продолжать т.к. попытка вставки провалилась
                }           

        } on PostgreSQLException catch(e) {
             print("Removing duplicates was FAILED: ${e.message}");
            }
    }    

    if (isDataWasInserted) {
      return dbEnums.success; 
    }

    else {
      writeLog("Can't insert data. Something wrong", ""); // нельзя продолжать т.к. попытка вставки провалилась
      return dbEnums.insertFailed; 
    }
  }

}


Как вообще найти причину тормозов?

Имеет ли смысл сделать индексы отложенными?
  • Вопрос задан
  • 108 просмотров
Пригласить эксперта
Ответы на вопрос 1
2ord
@2ord
продвинутый чайник
Нужно замерить обращения к БД и сопоставить с операциями. Если использовать APM, то обычно все будет наглядно представлено.
Везде, где можно, добавить метрики для замера.

Добавлено
взял один SQL INSERT и скормил его в SQL чтобы посмотреть за сколько он вставится.

Он отработал за 23 миллисекунды. Т.е. явно затык не в этом.
один insert ничего не покажет.
Надеюсь, вставка идет в виде batch по много строк за 1 запрос?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы