我在oracle数据库中有一个函数,它可以让我获得序列的下一个值。我也有以下PySpark代码:
def get_next_seq_value():
QUERY = "SELECT SCHEMA.GET_NEXT_SEQ_VALUE FROM DUAL"
sqlContext.clearCache()
next_seq_value_df = sqlContext.read.format("jdbc").options(url=URL, driver=DRIVER, QUERY=QUERY, user=USER, password=PASSWORD).load().unpersist()
next_seq_value = next_seq_value_df.take(1)[0][0]
return next_seq_value
我从这里调用这个函数:
array = []
for each_item in df_list:
next_seq_value = get_next_seq_value().encode('utf-8').strip()
array.append(next_seq_value)
问题如下:
当我运行以下命令时,数组看起来是这样的:
[' 545671 ', ' 545672 ', ' 545673 ', ' 545694 ', ' 545695 ', ' 545696 ']
为什么我看不到545674和545675…它只是跳到'545694'。如何确保按顺序调用函数?
默认顺序缓存大小为20:
如果省略CACHE和NOCACHE,则数据库默认缓存20个序列号。
所以看起来像是在你的呼叫之间的另一个称为nextval
的会话。
此外,从你的代码QUERY = "SELECT SCHEMA.GET_NEXT_SEQ_VALUE FROM DUAL"
看起来像你包装your_sequence.nextval
到函数GET_NEXT_SEQ_VALUE
。这里看起来有点小题大做:你会得到额外的调用(SQL->PL/SQL->调用.nextval()
)和这里的开销。您可以只使用select seq.nextval from dual
或:x := seq.nextval;
。如果想生成N个值,可以使用:select seq.nextval from dual connect by level<=20;
完全同意前面两个答案。我不确定您使用的是哪种类型的数据库架构,但我也想指出,使用Oracle RAC,每个集群节点实例也将有一个单独的序列缓存。
,
node 1: sequence cache 101-120
node 2: sequence cache 121-140
node 3: sequence cache 141-160
因此,根据碰巧处理请求的节点,nextval也可能不是按顺序排列的。
关键是,当使用序列时,您应该只计算唯一的值,而不一定没有间隔(消除缓存会严重影响性能),甚至不一定按顺序排列,这取决于您的物理服务器架构。如果要保持事情的顺序,无论什么是重要的,除了顺序计数器之外,还可以在记录中添加时间戳。您的问题显然是而不是顺序错误*序列生成ID
s,但间隙.
当你决定使用序列时,通常必须计算间隙.
如果您使用默认的缓存大小为20,那么您将在每个会话结束时平均丢失10ID
s。
你可以用NOCACHE
来减少这个,但即使在这里,你调用nextval
,然后回滚事务,这个ID可能会丢失。由于下一个事务通常以新的nextval
开始…