我有一个像这样的序列(在 PostgreSQL 16.0 中):
CREATE SEQUENCE public.seq_1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 999999999
START 1
CACHE 1
CYCLE;
integers
和一个包含0 到 1000000 的表
当我做:
select *, nextval('seq_1') as n2
from (
select i,n1,n1-i as d, sum(i) over (order by i) as s
from (
select i,nextval('seq_1') as n1
from integers
)
)
where i=0 or i=1000000
输出是:
我 | n1 | d | s | n2 |
---|---|---|---|---|
0 | 46137349 | 46137349 | 0 | 50331653 |
1000000 | 47137349 | 46137349 | 500000500000 | 50331654 |
n2
为什么第一行的值等于50331653?
我本来期望 47137349+1,我不介意小的差距,但在这种情况下,差距是 3194304 ( select 50331653 - 47137349
),这是很大的(或很大?)
我已经发现:
- postgres 9.0.4 序列跳过数字,所以我使用
CACHE 1
您显然熟悉对象的性质
SEQUENCE
- 正如您的预期结果所反映的那样。您的问题中没有任何内容可以解释其中的差异。我重新创建了测试用例并得到了
n2 = 47137350
预期的结果。在本地以及 Postgres 16 的小提琴中:小提琴
n2 = 50331653
你的结果令人惊讶。观察到的差异 3194303 是奇数,而不是 1000001 的简单倍数。
如果我从
SEQUENCE
at开始seq_1 = 1
,计算就会变得更加明显:您的数据库中一定发生了其他事情。要么是从同一序列中提取并发事务(似乎不太可能),要么是触发器,或者是奇怪的查询计划,导致烧毁超过 3 倍的序列号。这将由数据库中未反映在问题中的某些内容触发(索引、膨胀、服务器配置、列统计信息、损坏、客户端有问题的行为,...)。运行
EXPLAIN
orEXPLAIN ANALYZE
并与我的小提琴中的查询计划进行比较。(但老实说,我想不出可以做到这一点的查询计划。)
您刚刚创建了一个与表中的行数一样大的间隙,因此如果您想避免创建较大的间隙,请不要执行您刚才所做的操作。您以前做过多少次同样的动作?