【问题标题】:Insert fail then update OR Load and then decide if insert or update插入失败然后更新或加载,然后决定是插入还是更新
【发布时间】:2008-12-19 15:54:22
【问题描述】:

我在 java 中有一个 web 服务,它接收要在数据库中插入或更新的信息列表。不知道要插入还是更新哪一个。

哪一种是获得更好性能结果的最佳方法:

  1. 遍历列表(一个对象列表,上面有表pk),尝试在数据库中插入条目。如果插入失败,运行更新

  2. 尝试从数据库加载条目。如果检索到的结果更新,如果没有插入条目。

  3. 另一种选择?告诉我吧:)

在第一次调用中,我相信大多数条目将是新的 bd 条目,但会有一个饱和点,大多数条目将被更新。

我说的是一个成熟形式的数据库表,它可以达到超过 1 亿个条目。

你的方法是什么?性能是我最重要的目标。

【问题讨论】:

  • 表的主键是identity?
  • 没有。它不会在插入中自动递增。

标签: java database performance


【解决方案1】:

如果您的数据库支持 MERGE,我会认为这是最有效的(并将所有数据视为一个集合)。

见:

http://www.oracle.com/technology/products/oracle9i/daily/Aug24.html

https://web.archive.org/web/1/http://blogs.techrepublic%2ecom%2ecom/datacenter/?p=194

【讨论】:

    【解决方案2】:

    如果性能是您的目标,那么首先从您的词汇表中去掉迭代这个词!学习分组做事。

    如果您需要更新或插入,请始终先进行更新。否则很容易发现自己更新了不小心插入的记录。如果您这样做,那么拥有一个标识符会有所帮助,您可以查看该记录是否存在。如果标识符存在,则进行更新,否则进行插入。

    【讨论】:

      【解决方案3】:

      重要的是要了解插入次数与您收到的列表上的更新次数之间的平衡或比率。恕我直言,您应该实施一个抽象策略,即“将其保存在数据库中”。然后制定具体的策略(例如):

      1. 检查主键,如果找到零记录则插入,否则更新
      2. 进行更新,如果失败,进行插入。
      3. 其他

      然后从配置文件中提取要使用的策略(例如类完全限定名)。这样,您可以轻松地从一种策略切换到另一种策略。如果可行,可能取决于您的领域,您可以放置​​一个启发式算法,根据集合中的输入实体选择最佳策略。

      【讨论】:

        【解决方案4】:

        MySQL 支持这个:

        INSERT INTO foo
        SET bar='baz', howmanybars=1
        ON DUPLICATE KEY UPDATE howmanybars=howmanybars+1
        

        【讨论】:

          【解决方案5】:

          选项 2 不会是最有效的。当您执行实际插入或更新以强制执行主键时,数据库将已经为您进行此检查。通过自己进行此检查,您将产生两倍的表查找开销以及 Java 代码的额外往返。选择最有可能的情况并乐观地编码。

          扩展选项 1,您可以使用存储过程来处理插入/更新。这个使用 PostgreSQL 语法的例子假设插入是正常情况。

          CREATE FUNCTION insert_or_update(_id INTEGER, _col1 INTEGER) RETURNS void
          AS $$
              BEGIN
                  INSERT INTO
                      my_table (id, col1)
                  SELECT
                      _id, _col1;
              EXCEPTION WHEN unique_violation THEN
                  UPDATE
                      my_table
                  SET
                      col1 = _col1
                  WHERE
                      id = _id;
              END;
          END;
          $$
          LANGUAGE plpgsql;
          

          您也可以将更新设为正常情况,然后检查受更新语句影响的行数,以确定该行是否真的是新的并且您需要进行插入。

          正如在其他一些答案中提到的,处理此操作的最有效方法是批量处理:

          1. 获取传递给 Web 服务的所有行并将它们批量插入到临时表中
          2. 从临时表更新主表中的行
          3. 从临时表的主表中插入新行
          4. 处理临时表

          要使用的临时表的类型和最有效的管理方式取决于您使用的数据库。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-04-27
            • 2012-01-20
            • 2011-04-30
            • 2023-03-17
            • 1970-01-01
            • 1970-01-01
            • 2010-10-18
            • 1970-01-01
            相关资源
            最近更新 更多