【问题标题】:Check before, or manage the exception?检查之前,还是管理异常?
【发布时间】:2013-01-13 18:34:15
【问题描述】:

这是一个间接需求,但我想知道您在性能和设计方面有什么建议。

当你需要做某事时,什么会更快更好?检查你是否可以,如果你能做到。或者直接试一试,万一失败,你就明白执行的意思了。

这是我的特殊情况: 我有一个数据库表,我将使用 foreach 填充它。该表有一个不能在表中重复的主键。

所以..

foreach(object in Objects)
{
   bool exists = //SQL SELECT to check if exists.
   if (exists == false)
   {
      //SQL INSERT
      return INSERTED
    }
   else 
    {
     return failed
    }
}

    foreach(object in Objects)
    {
       try 
          {
          //SQL INSERT
          return INSERTED
           }
       catch
         {
        return FAILED
         }

    }

我想知道其他方面的最佳实践,例如创建不带覆盖属性的文件并管理 execpiton 或在尝试之前检查文件是否存在。

更新: 根据答案,我知道我不应该为每个插入进行事务,因为性能。我应该做一个批量插入。 在我的代码中,我有这样的东西

//SQL Start Transaction
foreach
{
//SQL INSERT
}
//SQL Commit transaction

我的问题是关于事务内部,我应该在插入之前检查还是只是尝试。

【问题讨论】:

  • 取决于重复的相对数量...
  • 我可以预测,但我认为平均值可能是 10 的 1。

标签: c# sql performance optimization database-performance


【解决方案1】:

异常的构造成本比布尔值高得多。

一些一般准则是仅将异常用于实际异常的行为(您不会将其视为正常事件),并避免将异常用于程序控制。

【讨论】:

    【解决方案2】:

    如果您想在 C# 中执行此操作,我建议创建主键的 HashSet,然后在尝试添加对象之前检查对象。

    注意:您应该确保不会在每次插入时都向数据库发送查询,因为这将比try/catchif 之间的任何差异慢得多

    进行插入的最快方法是将它们批处理到单个数据库调用中。

    【讨论】:

    • 谢谢。我刚刚根据您的回答更新了我的问题。你说的 Hashset 听起来很有趣,但不是因为我之前必须阅读所有数据库吗?
    【解决方案3】:

    通过 C# 进行的大量数据库操作非常低效且耗时。当我处理这个问题时,我通常不是检查,而是将插入构建到一个查询中;例如:

    "INSERT INTO sitemaps (link, site) 
     (SELECT ('" + NAME2 + "') as link, '" + SITE + "' as site 
       WHERE NOT EXISTS 
     (SELECT link FROM sitemaps 
        WHERE link = '" + NAME2 + "' and site='" + SITE + "')"
    

    这可以减轻数据库的负担并减少编码。

    另一种选择,提高插入性能(字面上数百倍)的非常好的方法是使用BULK INSERT(仅限MS SQL)到临时数据库表中(一次非常快地处理数千条记录);然后,在数据库端,使用MERGE 命令并编写 if-else 场景如何处理更新、插入、删除等。将前后部分移动到数据库始终是一个好习惯程序结束。

    【讨论】:

    • 必须确保在执行此类操作之前清理用户输入。否则,这很容易受到 SQL 注入攻击。
    猜你喜欢
    • 2018-05-09
    • 2018-01-22
    • 1970-01-01
    • 2018-10-18
    • 2012-08-20
    • 2012-01-02
    • 2019-06-19
    • 1970-01-01
    • 2021-12-31
    相关资源
    最近更新 更多