oracle - 序列 vs 最大主键值 + 1

标签 oracle

在表中插入新记录时,可以有两种方法,一种是找到主键列的最大值并对其加1或使用序列。哪种方法更好,为什么?

如果我们通过增加记录少于20,000条的表中主键列的最大值来找到下一个主键值有什么影响?

谢谢。

最佳答案

问:哪种方法更好,为什么?

A: 使用 SEQUENCE 对象是一种更好的方法。
MAX(id)+1 获取唯一 id 值的方法在多线程环境中被破坏,没有并发杀死锁定。这个问题在单用户测试中不会暴露;但是使用两个不同的 session 很容易证明这一点。考虑以下操作序列:

session 1:SELECT MAX(id)+1 AS next_id FROM mytable --> 42

第 2 节:SELECT MAX(id)+1 AS next_id FROM mytable --> 42

第 1 节:INSERT INTO mytable (id) VALUES (42)
第 2 节:INSERT INTO mytable (id) VALUES (42)
为了防止两个(或更多)单独的 session 返回相同的 next_id 值, session 有必要在执行查询之前获得表上的排他锁。它还需要持有该锁,直到将具有该 next_id 值的行插入到表中,然后再释放锁。当该 session 持有表的排他锁时,没有其他 session 可以查询或插入到表中,如果其他 session 尝试这样做,它们将被阻塞。 (我们不想通过引入这种锁定来降低数据库性能,这不是正确的方法,所以我们不会演示如何做到这一点。)

Oracle 提供 SEQUENCE 对象作为获取唯一值的有效方法,并且在多线程环境中对 SEQUENCE 对象的查询是“安全的”。为了在高负载下提高性能,我们会增加序列的“缓存”值,即内存中可用值的数量,这样我们就可以满足更多 NEXTVAL 请求而无需写入重做日志。

鉴于这两个选项,SEQUENCE 是更好的方法。

Q:在20000条记录以下的表中,通过增加主键列的最大值来找到下一个主键值有什么影响?

A: 检索索引列(索引中的前导列的列)的最大值并向其添加一个的查询应该是非常有效的,只要 session 能够获得所需的共享锁(也就是说, session 不会被排他锁阻塞。)

关于oracle - 序列 vs 最大主键值 + 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25980960/

相关文章:

sql - oracle plsql 将数字转换为天

c# - ORA-01882 : timezone region not found in Entity Framework

java - 如何在java应用程序中更新 session 超时的oracle表

java - 需要哪些 Oracle jdbc jar

sql - 数据库设计 : replace a boolean column with a timestamp column?

sql - 在 oracle 中存储日期

java - Oracle Database 12c - 无法使用使用 org.oracle.BLOB 对象的方法编译类

sql - 有没有办法在oracle sql中使用varchar2字符串的一部分作为主键?

sql - 如何在SQL中选择具有偶数ID号的列?

sql - 提高查询效率——减少全表扫描?