Oracle 18c可扩展序列

发布于:2021-02-20 00:00:22

0

111

0

Oracle Oracle 18c 数据库

索引块争用是具有高插入活动性的非常常见的数据库,在具有通常通过序列生成的单调递增键值的表上尤其常见。

Oracle B树索引是“右手的”索引,B树的右叶节点包含最高的键,该键位于最低的树级别。

当基于用户生成的键(例如通过序列)插入行时,以及在列由基于序列的键值填充的列的情况下,索引叶节点争用发生,最近的条目将位于B树的最右叶块中。

这意味着所有新行将存储在索引的最右边的叶块中。随着越来越多的会话向表中插入行,最右边的叶子块将满。

Oracle将最右边的叶子块分为两个叶子块,其中一个块包含除一行以外的所有行,而一个新块仅包含一行。

这种类型的指数增长称为“右手增长”指数。随着越来越多的并发会话插入到索引的最右边的叶块中,该索引块成为热块,并且该叶块上的并发导致性能问题。

在Oracle RAC数据库中,此问题被放大并成为更大的瓶颈。如果序列缓存(特定于实例)很小(默认为20),则最右边的叶子块不仅在一个实例中而且在所有实例中都成为群集的一部分,并且该热点块必须是通过互连来回传输。

Oracle Database 18c引入了一种称为可伸缩序列的新型序列。

现在在Oracle 18c中,在那些具有高并发性的数据摄取工作负载的情况下,通过生成无序的主键或唯一键值的新可伸缩序列有助于显着减少由右手索引引起的序列和索引块争用,从而提供了与必须使用CREATE SEQUENCE或ALTER SEQUENCE语句的CACHE子句配置非常大的序列缓存的Oracle 19c之前的解决方案相比,吞吐量,数据负载可伸缩性和性能更高。

可伸缩序列由序列偏移号组成,默认情况下包含6位数字

的前3位数字,从实例编号衍生100并将下一个3个位数从SID衍生该会话。

因此,假设具有SID 555且实例号为1的用户–则偏移号为101555,对于实例2中具有SID 666的另一个会话,偏移号为102666。

我们可以使用EXTEND of NOEXTEND选项创建可伸缩序列。

为SCALE子句指定EXTEND选项时,可伸缩序列值的长度为[X位数+ Y位数],其中X是序列偏移号,Y是MAXVALUE子句中指定的位数。

让我们看看使用EXTEND选项创建可伸缩序列时的工作方式。

请注意,每个实例中的序列生成的不同(无关和无序)值。

Instance 1

SQL> create sequence system.scale_ext_seq
 2  start with 1 increment by 1
 3  maxvalue 100
 4  scale extend;

Sequence created.

SQL> select system.scale_ext_seq.nextval from dual;

  NEXTVAL
----------
101007001


SQL> select sid from v$mystat where rownum = 1;

      SID
----------
7

Instance 2

SQL> select system.scale_ext_seq.nextval from dual;

  NEXTVAL
----------
102036021

SQL> select sid from v$mystat where rownum = 1;

      SID
----------
36

当为SCALE子句指定NOEXTEND选项时,可伸缩序列中的位数不能超过MAXVALUE子句中指定的位数。

请注意,当序列中的位数超过7(MAXVALUE子句1000000中的位数)时会发生什么。

SQL>create sequence system.scale_noext_seq
 start with 1 increment by 1
 maxvalue 1000000
 scale noextend;  

Sequence created.

INSTANCE 1

SQL> select system.scale_noext_seq.nextval from dual;

  NEXTVAL
----------
  1010071

SQL> /

  NEXTVAL
----------
  1010072

SQL> /

  NEXTVAL
----------
  1010073

...
...

  NEXTVAL
----------
  1010078

SQL> /

  NEXTVAL
----------
  1010079

SQL> /
select system.scale_noext_seq.nextval from dual
*
ERROR at line 1:
ORA-64603: NEXTVAL cannot be instantiated for SCALE_NOEXT_SEQ. Widen the
sequence by 1 digits or alter sequence with SCALE EXTEND.


SQL> alter sequence system.scale_noext_seq maxvalue 10000000;

Sequence altered.

SQL> select system.scale_noext_seq.nextval from dual;

  NEXTVAL
----------
 10100741



INSTANCE 2


SQL> select system.scale_noext_seq.nextval from dual;

  NEXTVAL
----------
 10203661