说明
在18c之前的版本中对于序列的使用,存在着对同一个序列争用的情况,特别是对于RAC这种高并发的环境中争用序列情况更是容易发生。针对这种情况,Oracle退出了可伸缩序列,大大减少了序列和所在索引的争用,并提供了更好的数据负载可伸缩性。而对于单实例也同样有用。
创建可伸缩序列
- 语法
通过加SCALE关键字就可以创建可伸缩序列
CREATE | ALTER SEQUENCE sequence_name
...
SCALE [EXTEND | NOEXTEND] | NOSCALE
...
可伸缩序列=6位可伸缩序列偏移量数+正常的序列
6位可伸缩序列偏移量数=[(instance id % 100) + 100]+[会话ID % 1000]
- EXTEND
表示序列总长度=[X个数字+Y个数字],X默认值是6位数,Y是MAXVALUE指定的位数。 - NOEXTEND
表示序列总长度不能超过MAXVALUE定义的长度,由于前面默认是6位数+正常的序列号,所以长度最少是7位数。
实验
创建EXTEND类型的可伸缩序列
- 查看会话ID和实例号
SQL> select sys_context('userenv','sid') from dual;
SYS_CONTEXT('USERENV','SID')
--------------------------------------------------------------------------------
69
SQL> select instance_number from v$instance;
INSTANCE_NUMBER
---------------
1
- 创建序列
SQL> create sequence lei_seq start with 1 increment by 1 minvalue 1 maxvalue 100 scale extend;
Sequence created.
- 查看序列值
SQL> select lei_seq.nextval from dual;
NEXTVAL
-----------------------
101069001 = 101+069+001
- 再开一个会话查看序列值
会话ID不同,生成的序列肯定不会相同,但是最后3位是依次增长的。
SQL> select sys_context('userenv','sid') from dual;
SYS_CONTEXT('USERENV','SID')
--------------------------------------------------------------------------------
101
SQL> select lei_seq.nextval from dual;
NEXTVAL
----------
101101002
创建NOEXTEND类型的可伸缩序列
SQL> create sequence lei_seq2 start with 1 increment by 1 minvalue 1 maxvalue 100 scale noextend;
Sequence created.
SQL> select lei_seq2.nextval from dual;
select lei_seq2.nextval from dual
*
ERROR at line 1:
ORA-64603: NEXTVAL cannot be instantiated for LEI_SEQ2. Widen the sequence by 4
digits or alter sequence with SCALE EXTEND.
可以看到报错了序列无法实例化,提示要么去掉maxvalue参数,要么使用extend。
错误原因很简单,因为noextend的可伸缩序列最少要7位数。
修改可以修改maxvalue为1000000即可,也就是6位数+1,一直增长到9就无法增长了,因为增长到10就会超过7位数。证明如下:
SQL> alter sequence lei_seq2 maxvalue 1000000;
Sequence altered.
重复执行几次
SQL> select lei_seq2.nextval from dual;
NEXTVAL
----------
1011011
SQL> /
NEXTVAL
----------
1011018
SQL> /
NEXTVAL
----------
1011019
SQL> /
select lei_seq2.nextval from dual
*
ERROR at line 1: --可以看到超过9就报错了,因为序列总长度超过了7位。
ORA-64603: NEXTVAL cannot be instantiated for LEI_SEQ2. Widen the sequence by 1
digits or alter sequence with SCALE EXTEND.
总结
对于可伸缩序列来说EXTEND和NOEXTEND没有本质区别,MAXVALUE代表的含义有所不同。
- 对于EXTEND来说MAXVALUE代表的后面正常序列的长度,而不是可伸缩序列的总长度。
- 对于NOEXTED来说MAXVALUE代表的是可伸缩序列的总长度。
注:Oracle建议对于可伸缩序列不要使用排序,因为它本身就是无序的。
参考连接: