- 什么情况下使用cache什么时间上使用nocache?
应该尽量使用cache,因为现在的数据库很多都是在高并发的情况下运行的,首先这样可以搞性能,并且也不会产生rowcache lock等待事件。可能有些人会担心数据库不正常的down掉会产生序列号间断,但这也是很少的情况。
当然如果你的业务要求是绝不能产生间断的序列号,那就要使用nochache了。
单机跳号
--创建序列
CREATE SEQUENCE NYYTEST.S_TEST
STARTWITH 1
INCREMENTBY 1
NOMINVALUE
MAXVALUE 10000
NOCYCLE
CACHE 20
NOORDER
-- 取值
select S_TEST.nextval from dual;--1
select S_TEST.nextval from dual;--2
--刷新共享池,清空 cache 中缓存的序列值
--刷新共享池会使所有的没有使用DBMS_SHARED_POOL.KEEP固定的对象全部被清除,所以共享池刚刚刷新的时候,SQL和PL/SQL的执行效率会略微下降
ALTER SYSTEM FLUSH SHARED_POOL;
-- 取值 会跳号
--由于cache的20个序列号已经从共享池中被清除,下次再取序列的nextval值取的是21
select S_TEST.nextval from dual;--21
集群跳号,回跳
cache会把sequence缓存在lb cache中,
序列是被共享的,两台机器cache了不同的两段seq
- A节点上序列缓存1-20,B节点序列缓存了21-40
- 第一次在A节点上请求nextval时,A将缓存值1-20并返回值1
- 如果负载算法是lru,下一个对nextval的请求发生在B节点上,B将缓存值21-40并返回值21 (跳号)
- 再下一次nextval的请求发生在A节点,此时如果A节点序列缓存没刷新,会返回值2 (回跳)
解决办法
- 设置cache为空
影响性能 - 序列设置为order,即采用cache + order
结论
sequence 只确保ID的唯一性
只设置cache属性
容易导致跳号
设置order属性
会保证唯一性
SEQUENCE cache原理:
- 设置no cache时, Oracle 直接从SEQUENCE 取下一个序列值
- 设置cache时, cache会缓存指定个数的序列值 , Oracle 会直接从 cache 中取下一个序列值, cache 中的序列值用完了,或者被手工清空 Oracle 会再次产生指定个数序列值并放置 cache 中供使用
oracle管理序列方法: 序列等待事件
图片转载于 https://blog.youkuaiyun.com/cpongo3/article/details/88799102
- row cache lock :
在 nocache 情况下,调用sequence.nextval过程中 保证序列的顺序性 - SQ锁(enq: SQ - contention) :
(cache+noorder) 调用sequence.nextval过程中 - SV锁(enq: SV - contention):dfs lock handel
cache+order情况下, RAC上节点之间顺序得到保障的的前提下,调用sequence.nextval期间拥有。
cache+order属性 为了保障顺序,集群实例之间需要不断的交换数据。因此性能稍差。单比nocache强
SELECT *
FROM V$EVENT_NAME
WHERE NAME IN (
'row cache lock',
'enq: SQ - contention',
'DFS lock handle',
'enq: SV - contention');
Oracle 11g R2. 单Instance数据库单会话循环不间断取值耗时测试:
序列参数 | 耗时 | 取值数量 |
---|---|---|
nocache | 2.26s | 10000 |
cache:20 | 0.46s | 10000 |
cache:100 | 0.37s | 10000 |
nocache: | 9.33s | 40000 |
cache:1000 | 1.31s | 40000 |