Oracle自适应序列
通常序列的作用主要是为了生成唯一的整数,用来作为表的主键字段。因为序列的数值一直在不断地增长,通常每次增加一。每一个新增的条目都会被放在索引的最右边叶子块,会使得这个叶子块非常的热,从而产生争用,如果是在一起RAC集群当中,那么就会争用的更加厉害,会导致更多的集群等待事件。
为了改善以序列值作为键值的表的数据加载性能,从Oracle 18.1数据库开始,自适应序列 (Scalable Sequences) 被引入这个特性为序列提供了添加 instance 和 session 偏移量的选项,当跨 RAC节点加载数据或者单实例多个进程并发加载数据时,可以显著减少序列争用和索引块争用的可能性。
这个新特性的好处是,在以序列作为键值的表的数据加载时,它通过减少争用来进一步提升Oracle数据库加载数据的能力。在创建序列的时候,将 instance 和 session 的 id 添加到序列的值中,这样在生成序列值时产生的争用和 insert 键值时产生的索引块争用可以显著的减少。这表明Oracle数据库数据的数据加载能力可以进一步扩展,并且可以支撑更高速率的数据加载。
创建自适应序列的语法如下
1 | CREATE | ALTER SEQUENCE [ schema. ]sequence |
有几个参数与普通序列的语法不同
SCALE/NOSCALE
当 SCALE 被指定的时候,一个数字偏移量会附着在序列值的开头。
偏移量的表现形式为 iii||sss|| ,其中,
iii 表现为一个3个数字的instance偏移量,数值来源为: (instance_id % 100) + 100,
sss 表现为一个3个数字的instance偏移量,数值来源为:(session_id % 1000)
|| 是连接符
EXTEND/NOEXTEND
当 EXTEND 和 SCALE 关键字同时被指定时,产生的序列值的长度都是 (x+y),这里 x 是自适应偏移量 (默认是6),而 y 则是序列的 maxvalue/minvalue 关键字限定的最大值的数字位数。举例来说,如果一个升序的序列,maxvalue 被指定为100,并且指定了SCALABLE EXTEND关键字,那么产生的序列值的表现形式为 iii||sss||001,iii||sss||002 …… iii||sss||100
默认情况下 SCALE 是 NOEXTEND 的,当 NOEXTEND 被设置时,产生的序列值长度最大只能是序列 maxvalue/minvalue 关键字限定的最大值的数字位数。在某些应用中,序列被用来填充固定宽度的列,那么在整合这些应用时,这个设定很有用。在调用一个 SCALABLE NOEXTEND 的序列的 NEXTVAL 值时,如果产生的序列值需要的数字位数比 maxvalue/minvalue 限定的最大值位数更大,那么一个用户错误会被抛出。
创建自适应序列
首先创建一个noscale的序列,则跟常规序列一样,这个也是默认值。
检查当前的instance_id和sid
1 | SQL> select sys_context('userenv','sid') from dual; |
1 | drop sequence my_seq; |
增加SCALE
属性,默认使用SCALE NOEXTEND
,则会自动增加6位数的前缀,总长度则跟maxvalue的位数保持一致
1 | SQL> drop sequence my_seq; |
101
为(instance_id % 100) + 100391
为(session_id % 1000)
如果打开一个新的会话去执行,可以看到中间的部分会发生改变
1 | SQL> select sys_context('userenv','sid') from dual; |
增加EXTEND
关键字,这个时候前面的6位数前缀不变,而是增加长度与maxvalue的最大值长度相等的序列
1 | SQL> col scale_seq for 999999999999999999 |
变更自适应序列
可以直接对已存在的序列进行属性的修改
1 | alter sequence my_seq noscale; |
查看已存在的自适应序列
1 | column sequence_name format a30 |