我听说过一些谣言,当主键列中的值发生更改时,应该删除行然后插入新值而不是更新列。
更新主键而不是删除/插入时是否会对性能产生影响?
更新主键时:
但是,如果您执行删除和插入操作,则删除两个点都会执行,而插入则更新索引。所以删除和插入没有任何好处。或者我不知道。
简而言之,进行两次操作而不是一次操作会更糟糕。不算删除是最难的操作。
虽然我坚信您应该设计物理模型以使外键尽可能稳定,但有时您确实需要更新一组键,例如由于重组。
让我们比较一下简单更新和删除+插入主键之间数据方面发生的情况。我们假设您的表被组织为一个堆(默认),并且现在表上没有外键或其他索引:
简单更新
删除+插入
PCTUSED
段的值),它将被添加到符合插入条件的块列表中。由于需要记录所有列的值,因此插入会导致更多的重做。当然,删除旧行并插入新行会导致旧索引条目的删除和新索引条目的创建(同上)。如果表有其他索引,情况会更糟,因为每个索引都需要为删除+插入维护(而主键更新不会触及它们,除非列重叠)。
如果有引用此表的键,则在这两种情况下都会遇到引用问题。如果该表引用其他表,您将再次在删除+插入中进行更多工作(除非引用再次基于主键列,在这种情况下它或多或少相同)。
结论:由于插入+删除会影响基表的所有列,因此它会比简单的更新造成更多的工作:更多的撤消、更多的重做以及对所有索引的两个操作(而不仅仅是主键索引)。
如果您的表是索引组织的,那么工作量将或多或少相同,因为行将被物理移动,但我很确定单个更新仍然比两个单个操作更有效(因为每个操作涉及开销)。
最大的性能和并发影响是当您在子表 FK 上没有索引时。在这种情况下,Oracle 没有其他选择,只能锁定整个子表并对其进行扫描以验证参照完整性。
也许这不知何故与主键上的 UPDATE 与 DELETE/INSERT 混淆了。可能是因为 Oracle 支持CASCADE ON DELETE
但不支持UPDATE
.
当您确实需要更新时,请不要使用 delete+insert。