序列有四种组合:
a. CACHE + NOORDER
b. CACHE + ORDER
c. NOCACHE + NOORDER
d. NOCACHE + ORDER
即使在单例配置下,当有大量的sequence需要产生的时候,性能压力和存储sequence值的行锁定代价相关。
NOCACHE与CACHE的性能
当使用cache时,dictionary cache(row cache)仅仅当出现新的水位线时才会更新一次。例如当cache是20,nextval第一次请求时,dictionary cache中的sequence的row cache值改变,增加20。DBA_SEQUENCES的LAST_NUMBER字段以cache值或20增加。抽取出存储于shared pool的20值,将会分配给请求nextval的session。v$_sequences(这个表应该不是Oracle官方提出的)允许知道sequence是否已经被缓存于shared pool中。
当不使用cache时,dictionary cache不得不对于任何nextval请求都有进行一次更新。意味着row cache不得不随着每次nextval的请求被锁定和更新。多个session同时请求一个nextval因此将会被block在一个’row cache lock'等待中。
当使用cache+order和RAC(cluster_database=true)时,需要使用序列中nextval的session需要得到一个排它实例SV锁,在shared pool中插入或更新序列值之前。当多个session同时需要同一个序列时,一些session将会等待'DFS lock handle'等待事件。
因为这些序列化机制的结果,整个序列,例如可能以最快的速度增长一个序列,不会随着RAC节点的个数扩展,当序列没有cache+序列order/序列没有order。相比于没有cache的序列,cache的序列性能更好。
由于非cache的order序列的序列化机制,序列的性能不会随着RAC节点个数扩展,例如性能不能提升。甚至性能会随着节点个数降低一些,例如因为要花费更多时间得到一个row cache锁或SQ入队列,特别是当参与更多节点时。但从1个节点扩展为2个节点时,性能降低的效果可见,从2个到3个时性能降低的效果也是可见的,但是当有更多的节点加入进来时则趋于平缓。
总结下,序列其实是有顺序的,只是默认是NOORDER,并行服务器才需要这种顺序,如果仅仅将序列作为主键不关注顺序那还好说。但使用序列也是有争抢的,因为要保证它的唯一性,所以对于并发量很大的系统可以采用CACHE,缓存一部分序列值,减少争抢,但同时需要冒着缓存丢失的风险,就像PCTFREE和PCTUSED这对参数一样,存在着不可调和的矛盾,找到一个平衡点才是关键。