繁体   English   中英

在使用 efcore 插入 PostgreSQL 数据库时尝试避免 UNIQUE 违规或捕获结果异常是否更快?

[英]Is it faster to try and avoid UNIQUE violations when inserting into a PostgreSQL database with efcore, or to catch the resulting exception?

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

我的假设是 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 来照顾它?

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM