Быстрее ли попытаться избежать УНИКАЛЬНЫХ нарушений при вставке в базу данных PostgreSQL с помощью efcore или перехватить полученное исключение? - PullRequest
0 голосов
/ 06 февраля 2020

Предполагая, что у меня есть ограничение UNIQUE для столбца в моей базе данных postgresql, является ли более производительным запрос к базе данных, прежде чем пытаться вставить новое значение, или допустимо перехватывать выброшенное исключение, когда база данных отклоняет запрос?

Я предполагал, что postgres проверит эти нарушения быстрее, чем требуется ядру EF для создания и выполнения запроса +, а затем запускает вставку. Так ли это?

try
{
    // _dctx is my DbContext
    _dctx.SomeTable.Add(newEntity);
    await _dctx.SaveChangesAsync();
}
catch (DbUpdateException ex)
{
    if (ex.InnerException is PostgresException npgex && npgex.SqlState == PostgresErrorCodes.UniqueViolation)
    {
        // Reached only when the UNIQUE constraint was violated
    }
    throw; // How other exceptions are handled isn't relevant to the question
}

против

try
{
    if (await _dctx.SomeTable.AnyAsync(x => x.UniqueProperty == hopefullyUniquePropertyValue))
    {
        // Handle duplicate insertion here
    }
    _dctx.SomeTable.Add(newEntity);
    await _dctx.SaveChangesAsync();
}
catch (DbUpdateException ex) {}

Поскольку это будет сделано одновременно / в нескольких экземплярах этой службы, я все еще буду ожидать, что эти исключения будут время от времени, но вопрос в том, будет ли накладные расходы на вызов AnyAsync() существенно больше, чем на разрешение базы данных + ORM позаботиться об этом?

1 Ответ

1 голос
/ 07 февраля 2020

Проверка наличия строки перед вставкой, безусловно, является худшим вариантом по двум причинам:

  • Вы выполняете две команды SQL: один запрос, чтобы проверить, существует ли строка, а другой - вставить новый. Это означает два сетевых обхода, две команды, выполняемые в базе данных ... Это намного тяжелее, чем одна вставка.
  • Возможно, база данных изменилась между вашей проверкой и вашей вставкой, поэтому вы можете получить уникальные нарушения ограничений в любом случае (что вы не проверяете в приведенном выше примере).

Однако, вместо того, чтобы обсуждать производительность в теории, всегда лучше просто сравнить два варианта (например, * 1009). * BenchmarkDo tNet).

...