11

可能重复:
Oracle RAC 和序列

我在本地环境中配置了 Oracle RAC。我分析了Sequnce的一个问题,就是nextVal生成的数字没有排序。假设我第一次获得值为 1 ,第二次获得值为 21 (我已将序列配置为默认 CACHE 20 和 NOORDER )。

在搜索时,我找到了解决方案,我需要订购序列。我有疑问哪个是更好的选择,

1) 缓存和排序

2) NOCACHE 和 ORDER

我想知道以上哪一项是更好的选择,为什么?

其次,如果我将序列更改为 NOCACHE 而不考虑 ORDER/NOORDER,我能否实现排序。

谢谢

4

1 回答 1

17

其次,如果我将序列更改为 NOCACHE 而不考虑 ORDER/NOORDER,我能否实现排序。

是的,因为 NOCACHE 是有效的,因为您在每次增量时强制写入 sys.seq$ 表,这也必须在节点上进行序列化。

--

我会在可能的重复中对已接受的答案提出异议。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.

即没有顺序的缓存。现在我们启动两个会话。我在此测试中使用 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.

因此选择 100,000 次序列迭代需要 7-8 秒。

现在让我们试试 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 分钟。

缓存+订单呢?

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 中;只有当前 + 最终数字)并考虑如果需要,请订购。

于 2012-11-22T15:27:22.323 回答