这个问题已经在这里有了答案:
已关闭8年。
我在本地环境中配置了Oracle RAC。我分析了Sequnce的问题,即nextVal生成的数字未排序。假设第一次我得到的值是1,第二次我得到的值是21(我将序列配置为默认的CACHE 20和NOORDER)。
在搜索中,我找到了解决方案,我需要对序列进行订购。我有一个疑问,哪个是更好的选择,
1)缓存和订购
2)NOCACHE和订购
我想知道以上哪个是更好的选择,为什么?
其次,如果我将顺序更改为NOCACHE而不考虑ORDER/NOORDER,是否可以实现排序。
谢谢
最佳答案
是的,因为您强制在每个增量上强制写入sys.seq $表,因此NOCACHE实际上是有序的,该表也必须在节点上进行序列化。
--
我会在可能的重复中对接受的答案提出异议。 RAC中的CACHE + ORDER和NOCACHE有很大的不同。您不是在用ORDER否定CACHE;只是降低其有效性。我个人看到中间层应用程序的性能急剧下降,因为他们在序列上使用NOCACHE并同时在多个节点上进行访问。我们将他们的顺序切换为ORDER CACHE(因为他们想要一个跨种族的订单)。并大大提高了性能。
总结:顺序速度从“最快”到“最慢”依次为“CACHE NOORDER”->“CACHE ORDER”,以及“NOCACHE”后面的方式。
这也很容易测试:
因此,我们从一个标准序列开始:
SQL> create sequence daz_test start with 1 increment by 1 cache 100 noorder;
Sequence created.
即CACHE没有顺序。现在,我们启动两个 session 。在此测试中,我使用的是4节点RAC数据库10.2.0.4:
我的测试脚本很简单
select instance_number from v$instance;
set serverout on
declare
v_timer timestamp with time zone := systimestamp;
v_num number(22);
begin
for idx in 1..100000
loop
select daz_test.nextval into v_num from dual;
end loop;
dbms_output.put_line(systimestamp - v_timer);
end;
/
/
现在我们运行第一个测试(CACHE NOORDER):
SESSION 1 SESSION 2
SQL> @run_test SQL> @run_test
INSTANCE_NUMBER INSTANCE_NUMBER
--------------- ---------------
2 1
PL/SQL procedure successfully completed. PL/SQL procedure successfully completed.
PL/SQL procedure successfully completed. PL/SQL procedure successfully completed.
SQL> @run_test SQL> @run_test
INSTANCE_NUMBER INSTANCE_NUMBER
--------------- ---------------
2 1
+000000000 00:00:07.309916000 +000000000 00:00:07.966913000
PL/SQL procedure successfully completed. PL/SQL procedure successfully completed.
+000000000 00:00:08.430094000 +000000000 00:00:07.341760000
PL/SQL procedure successfully completed. PL/SQL procedure successfully completed.
因此,需要7-8秒来选择该序列的100,000次迭代。
现在让我们尝试NOCACHE(对此,ORDER与NOORDER是无关紧要的,因为我们在每次调用该序列时都强制对seq $进行写操作)。
SQL> alter sequence daz_test nocache;
Sequence altered.
SESSION 1 SESSION 2
SQL> @run_test SQL> @run_test
INSTANCE_NUMBER INSTANCE_NUMBER
--------------- ---------------
2 1
+000000000 00:08:20.040064000 +000000000 00:08:15.227200000
PL/SQL procedure successfully completed. PL/SQL procedure successfully completed.
+000000000 00:08:30.140277000 +000000000 00:08:35.063616000
PL/SQL procedure successfully completed. PL/SQL procedure successfully completed.
因此对于相同的工作集,我们从8秒跳到8分钟。
那CACHE + ORDER呢?
SQL> alter sequence daz_test cache 100 order;
Sequence altered.
SQL> @run_test SQL> @run_test
INSTANCE_NUMBER INSTANCE_NUMBER
--------------- ---------------
2 1
+000000000 00:00:25.549392000 +000000000 00:00:26.157107000
PL/SQL procedure successfully completed. PL/SQL procedure successfully completed.
+000000000 00:00:26.057346000 +000000000 00:00:25.919005000
PL/SQL procedure successfully completed. PL/SQL procedure successfully completed.
因此,总计有100,000次单次调用访存
CACHE NOORDER = 8秒
NOCACHE = 8分钟
CACHE ORDER = 25秒
对于缓存顺序,oracle确实在RAC节点之间执行了许多ping操作,但是它必须将内容写回到seq $,直到缓存大小用完为止,因为所有操作都在内存中完成。
我会(如果我是您的话)设置一个适当的缓存大小(ps高的缓存大小不会给存储盒内存带来负担,因为oracle不会将所有数字存储在RAM中;仅是当前+最终数字)并考虑订购(如果需要)。
关于Oracle Sequence值未排序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13513936/