这个问题已经在这里有了答案:




已关闭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/

10-09 15:40