在使用 efcore 插入 PostgreSQL 数据库时,尝试避免 UNIQUE 违规是否更快,或者捕获由此产生的异常



>假设我对 postgresql 数据库中的列有一个 UNIQUE 约束,那么在尝试插入新值之前查询数据库是否性能更高,还是在数据库拒绝查询时捕获抛出的异常是否可以接受?

我的假设是,postgres 检查这些违规的速度比 EF core 构造和执行查询 + 然后运行插入所需的时间更快。是这样吗?

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 处理它的开销?

在插入之前检查行是否存在绝对是最糟糕的选择,原因有两个:

  • 您正在执行两个 SQL 命令:一个查询用于检查该行是否存在,另一个用于插入新命令。这意味着两次网络往返,在数据库中执行两个命令......它比单个插入物重得多。
  • 数据库可能在检查和插入之间发生了变化,因此在任何情况下都可能收到唯一的约束冲突(您在上面的示例中没有检查(。

然而,与其在理论上讨论性能,不如简单地对这两个选项进行基准测试(使用类似BenchmarkDotNet的东西(。

相关内容

最新更新