带CACHE选项的序列nextval值异常:为何返回21而非14?
为什么带CACHE选项的序列nextval返回21?
这是PostgreSQL序列CACHE选项的正常行为,核心原因是序列缓存会为每个会话预分配一批值,未使用的缓存值会随会话结束丢弃,且不同会话的缓存相互独立,具体拆解:
针对reviews_seq的行为解释
你的reviews_seq设置了CACHE 10,意味着每个数据库连接(会话)会预取10个序列值存到内存,减少磁盘IO开销:
- 第一个会话插入数据时,会预取
1-10这10个值,同时序列的持久化last_value会更新为10。 - 若插入10条后关闭会话,或者换另一个会话插入剩下的3条,新会话会预取下一批
11-20的值,序列的last_value更新为20。此时只用了11-13,剩下的14-20留在该会话的缓存中。 - 当你新开会话执行
SELECT nextval('reviews_seq');时,新会话没有缓存,会直接申请下一批21-30的值,因此返回21。
哪怕你在同一个会话插入13条,之后关闭该会话再开新会话执行nextval,也会返回21——因为原会话缓存里的14-20随会话结束被丢弃,序列的持久化值已经是20,新会话只能从21开始预取。
针对products_seq的行为解释
products_seq未设置CACHE,默认是CACHE 1,也就是每次调用nextval都会直接从序列的持久化存储读取最新值,用完立即更新持久化的last_value。不管用多少会话插入,插入13条后序列的last_value就是13,因此下一次nextval自然返回14。
补充说明
CACHE选项是为了提升序列访问性能,但代价是可能出现序列值“跳号”(比如上述的14-20被丢弃,直接跳到21)。如果业务要求序列值严格连续,就不要使用CACHE;如果能接受跳号换取性能,这个行为完全符合设计预期。
内容的提问来源于stack exchange,提问作者ovod
相关产品推荐
相关产品推荐

