【问题标题】:UPDATE vs INSERT performance更新与插入性能
【发布时间】:2011-11-10 02:43:56
【问题描述】:

我认为UPDATE 查询比INSERT 查询占用更多资源是否正确?

【问题讨论】:

  • 你为什么要比较这些?它们的用途完全不同,因此通常您别无选择 - 只需使用能胜任工作的那个即可。
  • @Lukasz Milewski 如果速度更快并且您实际上得到相同的结果,您可以选择删除表,然后插入与更新。有时删除然后重写所有行比让 MySQL 确定行是否需要更新更快
  • 问题应该提到UPDATE 是否涉及单行以及INSERT 是否创建单行。响应也可能取决于操作是否发生在事务中。

标签: mysql sql


【解决方案1】:

我不是数据库专家,但这是我的两分钱:

我个人认为您在这方面没有太多工作要做,即使 INSERT 会更快(所有有待证明),您可以在插入中转换更新吗?!坦率地说,我不认为你可以一直这样做。

在 INSERT 期间,您通常不必使用 WHERE 来识别要更新的行,但根据您在该表上的索引,操作可能会产生一些成本。

在更新期间,如果您不更改包含在任何索引中的任何列,则可以快速执行,前提是 where 子句足够简单和快速。

没有什么是写在石头上的,我真的想这取决于整个数据库设置、索引等等。

总之,找到了这个作为参考:

Top 84 MySQL Performance Tips

【讨论】:

  • 有时您可以使用 INSERT...ON DUPLICATE KEYS UPDATE 通过 INSERT 部分模拟 UPDATE。但我相信在这种情况下,如果有重复项,MySQL 会先执行 INSERT,然后再执行 UPDATE,因此您最终会得到两个查询,这应该比单个 UPDATE 慢。
【解决方案2】:

如果您计划执行大型处理(例如为移动电话公司计费或计费),此问题会对系统性能产生巨大影响。

事实证明,执行大规模更新与创建许多新表和索引相比,可以将我公司的计费流程从 26 小时缩短到 1 小时!

我已经为 100,000 名客户尝试了 200 万条记录。 我首先创建了计费表,然后每个客户汇总调用,我用持续时间、价格、折扣.. 总共 10 个字段更新了计费表。

在第二个选项中,我创建了 4 个阶段。 每个阶段读取前一个表,创建索引(在表插入完成后)并使用:“insert into from select ..”我已经为下一阶段创建了下一个表。

总结 尽管第二种选择需要更多的磁盘空间(最后删除所有视图和临时表),但此选项有 3 个主要优点: 1. 比选项 1 快 4 倍。 2. 如果流程中间出现问题,我可以从失败的点开始流程,因为阶段开始的所有表都已准备好,流程可以从这一点重新启动。如果该过程未能实施第一个选项,您将需要重新启动所有过程。 3. 这使得开发和 QA 工作更快,因为他们可以并行工作 .

【讨论】:

    【解决方案3】:

    这里的关键资源是磁盘访问(准确地说是 IOPS),我们应该评估哪些资源会导致最低限度。

    同意其他人不可能给出一个通用的答案,但有一些想法可以引导你朝着正确的方向前进,假设一个简单的键值存储和键被索引。插入是插入一个新键,更新是更新现有键的值。

    如果是这种情况(一种非常常见的情况),更新将比插入更快,因为更新涉及索引查找和更改现有值而不触及索引。您可以假设这是一次磁盘读取以获取数据,并且可能是一次磁盘写入。另一方面,插入将涉及两次磁盘写入,一次用于索引,一次用于数据。但另一个隐藏成本是 btree 节点拆分和新节点创建,这将在后台发生,同时插入会导致平均更多的磁盘访问。

    【讨论】:

      【解决方案4】:

      一般来说,您无法比较 INSERT 和 UPDATE。给我们一个例子(带有模式定义),我们将解释哪个成本更高以及原因。此外,您可以通过检查它们的计划和执行时间来计算具体的 INSERT 和 UPDATE。

      一些经验法则:

      • 如果您只更新一个未编入索引的字段,并且您只更新一条记录并使用 rowid/主键查找该记录,那么此 UPDATE 的成本将低于
      • 一个 INSERT,它也只会影响一行,尽管该行将有许多非空约束的索引字段;并且所有这些索引都必须维护(例如添加新叶子)

      【讨论】:

        【解决方案5】:

        这取决于。在 WHERE 子句中使用主键并仅更新单个非索引字段的简单 UPDATE 可能比同一张表上的 INSERT 成本更低。但即便如此,这也取决于所涉及的数据库引擎。然而,涉及修改许多索引字段的 UPDATE 可能比该表上的 INSERT 成本更高,因为需要更多的索引键修改。带有结构不佳的 WHERE 子句(需要对数百万条记录进行表扫描)的 UPDATE 肯定会比在该表上的 INSERT 更昂贵。

        这些语句可以采用多种形式,但如果您将讨论限制在涉及单个记录的“基本”形式,那么大部分成本通常将用于修改索引。在 UPDATE 期间修改的每个索引字段通常会涉及两个基本操作(删除旧键并添加新键),而 INSERT 则需要一个(添加新键)。当然,聚集索引随后会添加一些其他动态,如锁定问题、事务隔离等。因此,最终,一般意义上的这些语句之间的比较实际上是不可能的,如果它确实可能需要对特定语句进行基准测试很重要。

        不过,通常情况下,只使用正确的语句而不用担心它是有意义的,因为它通常不是在 UPDATE 和 INSERT 之间进行选择的选项。

        【讨论】:

          【解决方案6】:

          这取决于。如果更新不需要更改键,则很可能它只会像搜索一样花费,然后它可能会比插入花费更少,除非数据库像堆一样组织。

          这是我唯一能说的,因为性能很大程度上取决于所使用的数据库组织。

          例如,如果您使用我认为像 isam 一样组织的 MyISAM,则插入在数据库读取访问方面的成本应该大致相同,但它需要一些额外的写入操作。

          【讨论】:

            【解决方案7】:

            在 Sybase / SQL Server 上,影响具有只读索引的列的更新在内部被删除然后插入替换,因此这显然比插入慢。我不知道其他引擎的实现,但我认为至少在涉及索引时这是一种常见的策略。 现在对于没有索引的表(或不涉及任何索引的更新请求),我想在某些情况下更新可以更快,具体取决于表的结构。

            【讨论】:

              【解决方案8】:

              在 mysql 中,您可以使用 ON DUPLICATE KEY UPDATEupdate 更改为 insert

              INSERT INTO t1 (a,b,c) VALUES (1,2,3)
                ON DUPLICATE KEY UPDATE c=c+1;
              
              UPDATE t1 SET c=c+1 WHERE a=1;
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-10-11
                • 1970-01-01
                • 1970-01-01
                • 2012-03-31
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多