主键更新vs主键删除+插入

时间:2013-09-23 11:30:54

标签: oracle oracle11g

我听说过一些传言,当主键列中的值发生变化时,应删除行,然后插入新值而不是更新列。

主键更新但未删除/插入时是否会影响性能?

3 个答案:

答案 0 :(得分:5)

更新主键时:

  • 支持索引已更新。
  • 如果是外键将被检查 对于孩子们。

但是如果你执行删除和插入操作,则执行删除操作和插入时,将更新索引。所以删除和插入没有任何好处。或者我都不知道。

很快,做两次操作而不是一次操作会更糟。不计算删除是最难的操作。

答案 1 :(得分:3)

虽然我坚信您应该设计物理模型以使外键为as stable as possible,但有时您确实需要更新一组键,例如由于重组。

让我们比较简单更新和主键的删除+插入之间数据面发生了什么。我们假设您的表被组织为一个堆(默认),并且现在表中没有外键或其他索引:

  1. 简单更新

    • 数据已修改:表格的行数据将直接在块中修改。主键列通常很小,因此不太可能迁移行。主键索引充当常规索引:对键的更新将导致指向旧键的条目被删除,同时将插入指向新值的新条目。
    • 重做条目:更新的重做将包含对数据进行的物理更改:单列更新(小重做)和索引删除+插入。
    • 撤消条目:撤消将包含旧列值(小撤消)和反向插入+删除索引。

  2. 删除+插入

    • 数据已修改(重做):Oracle必须以物理方式删除该行并插入另一行。从直接数据的角度来看,删除行是一个简单的操作:找到包含该行的块,并将该行标记为已删除。如果该块仍包含足够数量的数据(其他未删除的行),则它将保持原样。如果不是(低于段的PCTUSED值),它将被添加到符合插入条件的块列表中。由于需要记录所有列的值,因此插入会导致更多重做。当然,删除旧行并插入新行将导致删除旧索引条目和创建新索引条目(与上面相同)。
    • 撤消条目:删除操作需要记录旧行的所有列的值。另一方面,插件在撤消时受到保护,只是简单的删除。
  3. 如果表中有其他索引,那就更糟了,因为需要为delete + insert维护每个索引(除非列重叠,否则它们不受主键更新的影响)。

    如果有引用此表的键,则在这两种情况下都会遇到引用问题。如果表引用了其他表,那么你将在delete + insert中有更多的工作(除非引用再次基于主键列,在这种情况下它将或多或少相同)。

    结论:由于insert + delete会影响基表的所有列,因此它会比简单更新产生更多的工作:更多撤消,更多重做以及对所有索引的两个操作(而不是主键索引。)

    如果你的表是索引组织的,那么工作量或多或少会相同,因为行将在物理上移动,但我很确定单个更新仍然比两个单独的操作更有效(因为每个操作都涉及开销)。

答案 2 :(得分:1)

最大的性能和并发影响是当您没有子表FK的索引时。在这种情况下,Oracle没有其他选择,然后锁定整个子表,扫描它以验证参照完整性。

也许这与主键上的UPDATE vs. DELETE / INSERT混淆了。也许是因为Oracle支持CASCADE ON DELETE但不支持UPDATE

当您需要更新时,只需不要使用delete + insert。