定义Sequence是很简单的,如果最大程度利用默认值的话,我们只需要定义sequence对象的名字即可。在序列Sequence对象的定义中,Cache是一个可选择的参数。默认的Sequence对象是有cache选项的,默认取值为20。这个默认值对于大多数情况下都是够用的。 除非那种每秒上万次的select。 所以具体情况要具体对待。 对于哪些大并发的系统,最好设置在100以上。像移动的BOSS系统,以1000为单位。
SEQUENCE 创建基本语法:
CREATE SEQUENCE [schema.]sequence
[INCREMENT BY integer]
[START WITH integer]
[MAXVALUE integer | NOMAXVALUE]
[MINVALUE integer | NOMINVALUE]
[CYCLE | NOCYCLE]
[CACHE integer | NOCACHE]
[ORDER | NOORDER]
eg:
CREATE SEQUENCE emp_seq
INCREMENT BY 1-- 每次加几个
START WITH 1 -- 从1开始计数
NOMAXVALUE -- 不设置最大值
NOCYCLE -- 一直累加,不循环
CACHE N / NOCACHE --其中n代表一个整数,默认值为20。
如果指定CACHE值,Oracle就可以预先在内存里面放置一些Sequence,这样存取的快些。cache里面的取完后,Oracle自动再取一组到cache。使用cache或许会跳号, 比如数据库突然不正常down掉(shutdown abort),cache中的Sequence就会丢失。举个例子:比如你的sequence中cache 100,那当你sequence取到90时突然断电,那么在你重启数据库后,sequence的值将从101开始。
如果指定NOCACHE值,Oracle就不会预先在内存里面存放Sequence,当然这也就可以避免数据库不正常down掉的sequence丢失。不过会产生一些问题:创建nocache sequence在高并发访问时,容易导致row cache lock等待事件,主要原因是每次获取nextval时都需要修改rowcache中的字典信息。使用nocache sequence,还会导致如下问题:
由于每次修改字典信息都需要commit,可能导致log file sync等待,nocache sequence在RAC环境下,会对基于sequence生成的列创建的索引造成实例间大量索引块争用
基于以上问题,避免创建nocache sequence。
再来看看sequence相关保护机制:
row cache lock:在调用sequence.nextval情况下需要修改数据字典时发生,对应row cache lock事件
SQ lock:在内存缓存(并非rowcache)上获取sequence.nextval时发生,对应enq:SQ-contention事件
SV lock:RAC环境下获取cache+order属性的sequence.nextval时发生,对应DFS lock handle事件
什么情况下使用cache什么时间上使用nocache?
个人感觉应该尽量使用cache,因为现在的数据库很多都是在高并发的情况下运行的,首先这样可以搞性能,并且也不会产生row cache lock等待事件。可能有些人会担心数据库不正常的down掉会产生序列号间断,但这也是很少的情况。当然如果你的业务要求是绝不能产生间断的序列号,那就要使用nochache了。
序列的并发访问 :
序列总是在数据库中生成唯一值,即使当多个用户并发地引用同一序列时也没有可察觉的等待或锁定。当多个用户使用 NEXTVAL 来增长序列时,每个用户生成一个其他用户不可见的唯一值。
当多个用户并发地增加同一序列时,每个用户看到的值是有差异的。例如,一个用户可能从一个序列生成一组值,如 1、4、6 和 8,而另一个用户并发地从同一序列生成值 2、3、5 和 7。
假如在创建sequence时,有意不选用cache选项,有2点需要注意:
1. 访问效率降低,没有cache功能的sequence取值将无法直接访问内存
2. 不论是nocache还是cache , 每次访问nextval的过程都是不可逆的,在同一session中,在执行一系列dml和sequence的操作后,用户执行rollback,希望将操作回滚,但是sequence此时就显得异常顽固,用掉的nextval将无法被重现。当下一次试图读取nextval时,sequence的指针又移动到下一位了。
还有sequence不属于某个表,也不属于某个字段,sequence仅仅属于某个用户。
其实在创建了sequence后,每个表都可以使用这个sequence,但是这样会引起应用的很多麻烦,因此,建议每个表都使用一个sequence。
以上参考文献:
http://blog.csdn.net/cymm_liu/article/details/7451009 ;
关于Sequence order 参数的说明:
序参数:oracle默认是NOORDER,如果设置为ORDER;在单实例环境没有影响,在RAC环境此时,多实例实际缓存相同的序列,此时在多个实例并发取该序列的时候,会有短暂的资源竞争来在多实例之间进行同步。因次性能相比noorder要差,所以RAC环境非必须的情况下不要使用ORDER,尤其要避免NOCACHE ORDER组合。
order确保按照请求次序递增生成序列数字,在RAC环境中建议使用该选项。noorder不保证按请求次序生成,默认是noorder。
Cache参数对Sequence的使用带来什么好处?如果不设置,会有什么问题 ?
1、Sequence Cache简析
简单的说,Cache 就是Oracle每次向Sequence进行请求时,分配出的独立数字数量。例如,当我们使用<seq_name>.nextval获取一个 独立值时,Oracle需要将sequence对象的数据字典信息更新。如果我们设置cache为10,那么第一次请求nextval的时候,就更新数据 字典信息增加10,取出的10个号放在Oracle服务器的缓存中。
在以后每次请求nextval的时候,Oracle就从服务器缓存中去获取序列值。而不需要更新数据字典信息。只有在分配到缓存的10个数字都已经分配完,或者因为缓存刷新操作剩余数字被清理的情况下,才会再次调用sequence分配机制,再次分出cache个数字。
在cache问题上,我们经常会疑惑为什么我们sequence生成的数字序列会“跳号”。这种跳号现象实际上就是因为cache的数字在缓存中因为各种原因被flush出,这样才导致生成的数字序列不连续。
注意:在有cache的情况下,sequence只能保证每次获取到的数字都是唯一、递增的,从来没有保证过数字的连续性。
如果我们不设置cache,也就是不启用序列数字缓存机制,有什么缺点呢?
1、过多的Redo Log生成
a),对nocache的序列对象而言,每次操作都会有600左右的redo log生成。
b),对cache的sequence对象而言,redo size生成的频率显然是低得多(到达cahce size最大值时才会创建redo log)。
设置cache之后,Oracle似乎不用为每次的nextval进行数据字典修改,生成redo log记录。只有cache在内存中使用结束之后,才会进行获取。
在实际的生产环境中,我们对redo size无必要的生成是要尽力避免的。首先,过多的redo log生成,容易造成online redo log的写入量增加,切换频繁。第二,redo size和nocache的使用,可能是伴随着频繁的commit动作,进而是频繁的log buffer写入online log file的过程。同时归档量增加。同时,在进行恢复的时候,也要消耗更多的时间。
所以,设置cache可以有效减少redo log的大小。
说明:
如果我们处在一个高并发的情况下,系统频繁的多会话请求sequence取值。如果我们的sequence没有设置cache,那么每次都要更新数据字典,都要进行commit操作。多个会话还会出现该sequence记录的争用,出现等待事件row lock contention。
在RAC环境下,cache和noorder选项的作用更大。在RAC中,多个实例争用情况会让sequence设计的不合理效果放大。所以,在没有特殊情况下,还是设置合理的cache值,减少系统潜在性能瓶颈。
以上参考文献:
http://www.cnblogs.com/liuhouhou/archive/2012/08/15/2639808.html ;
oracle RAC 环境解决sequence 不一致问题:
http://wenku.baidu.com/view/75467cf2fab069dc50220135.html ;
转载于:https://blog.51cto.com/bincto/1276269