序列与最大主键值+ 1

FIr*_*nda 4 oracle

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

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

谢谢.

spe*_*593 13

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

答:使用SEQUENCE对象是一种更好的方法.

MAX(id)+1来获得方法唯一 ID值打破在多线程环境中,不存在并发杀人锁定.单个用户测试不会暴露此问题; 但是使用两个不同的会话来演示这个很容易.考虑这一系列操作:

第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)

为了防止两个(或多个)单独的会话返回相同的next_id值,会话必须在执行查询之前获取表上的独占锁.next_id在释放锁之前,它还需要保持该锁,直到将具有该值的行插入表中.虽然该会话持有表的独占锁,但没有其他会话可以查询或插入表中,其他会话将在它们尝试时阻止.(我们不想通过引入这种锁定来破坏数据库性能,这不是正确的方法,所以我们不会演示如何做到这一点.)

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

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


问:如果我们通过在少于20,000条记录的表中递增主键列的最大值来找到下一个主键值,会产生什么影响?

答:只要会话能够获得所需的共享锁定,检索索引列(作为索引中的前导列的列)的最大值并向其添加一个的查询应该非常高效(即,会话不会被独占锁阻止.)