UPDATE vs INSERT性能

时间:2011-09-04 14:08:57

标签: mysql sql

我是否认为UPDATE查询比INSERT查询需要更多资源?

谢谢,

8 个答案:

答案 0 :(得分:8)

我不是数据库大师但是我的两分钱:

就我个人而言,我认为你在这方面没有太多事情要做,即使INSERT更快(都需要证明),你能否在插入中转换更新?!坦率地说,我认为你不能一直这样做。

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

在更新期间如果你没有更改任何索引中包含的任何列,你可以快速执行,如果where子句容易且足够快。

没有任何东西写在石头上,我真的想象它取决于整个数据库设置,索引等等。

无论如何,发现这个作为参考:

Top 84 MySQL Performance Tips

答案 1 :(得分:2)

如果您计划执行大型处理(例如蜂窝公司的评级或计费),此问题会对系统性能产生巨大影响。

执行大规模更新与制作许多新表和索引已经证明可以将我公司的结算流程从26小时减少到1小时!

我已经为100,000名客户在200万条记录上进行了尝试。 我首先创建了账单表,然后是每个客户摘要电话,我用持续时间,价格,折扣更新了账单表。总计10个字段。

在第二个选项中,我创建了4个阶段。 每个阶段读取前一个表,创建索引(在表插入完成后)并使用:"从select中插入..."我为下一阶段创建了下一个表格。

概要 虽然第二种替代方案需要更多的磁盘空间(最后删除所有视图和临时表),但此选项有3个主要优点: 1.它比选项1快4倍。 2.如果在流程中间出现问题,我可以从失败的角度开始流程,因为阶段开始的所有表都已准备就绪,流程可以从此点重新启动。如果进程未能实现第一个选项,则需要重新启动所有进程。 这使得开发和QA工作更快,因为它们可以并行工作

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:1)

这取决于。如果更新不需要更改密钥,那么它很可能只会像搜索一样,然后它的成本可能会低于插入,除非数据库像堆一样组织。

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

例如,如果你使用我认为像isam组织的MyISAM,那么在数据库读访问方面,insert的成本通常是相同的,但它需要一些额外的写操作。

答案 4 :(得分:1)

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

答案 5 :(得分:1)

这里的关键资源是磁盘访问(确切地说是IOPS),我们应该评估哪些结果最少。

与其他人就如何不可能提供一般性答案达成一致,但有些想法可以引导您朝着正确的方向前进,假设一个简单的键值存储和键被索引。插入正在插入新密钥,更新正在更新现有密钥的值。

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

答案 6 :(得分:0)

您通常无法比较INSERT和UPDATE。给我们一个例子(使用模式定义),我们将解释哪一个成本更高,为什么。此外,您可以通过检查其计划和执行时间来主持具体的INSERT和UPDATE。

虽然有些规则:

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

答案 7 :(得分:0)

在 mysql 中,您可以使用 ON DUPLICATE KEY UPDATE

update 更改为 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;
相关问题