2012-11-22 97 views
10

可能重複:
Oracle RAC and sequences甲骨文序列值是無序的

我在我的本地環境配置的Oracle RAC。我用Sequnce分析了一個問題,即nextVal生成的數字未被排序。假設第一次我得到的值爲1,第二次得到的值爲21(我已經配置了序列與默認CACHE 20和NOORDER一樣)。

在搜索我找到了解決方案,我需要訂購序列。我有問題,這是更好的選擇去用,

1)CACHE和ORDER

2)NOCACHE和ORDER

我想知道哪些上面一個是更好的選擇,爲什麼?

其次,如果我將序列更改爲NOCACHE而不考慮ORDER/NOORDER,我可以實現排序嗎?

感謝

回答

15

其次,我能做到的排序,如果我改變的順序是 NOCACHE不論ORDER/NOORDER的。

是的,因爲NOCACHE是有效的命令,因爲你迫使每個增量sys.seq $表寫入,每個增量必須在節點上串行化。

-

我會質疑在可能的重複中接受的答案。 RAC中的CACHE + ORDER和NOCACHE存在巨大差異。你不是用ORDER否定CACHE;只是降低其有效性。我個人認爲中間層應用程序的性能會急劇下降,因爲他們在一個序列上使用了NOCACHE,並且一次訪問多個節點。我們將它們的序列切換到ORDER CACHE(因爲他們想要交叉命令)。性能大幅提升。

總結:該序列的速度將是最快到最慢作爲「CACHE NOORDER」 - >「CACHE令」的方式方法遠遠落後「NOCACHE」。

這是容易測試過:

所以我們先從一個標準序列:

SQL> create sequence daz_test start with 1 increment by 1 cache 100 noorder; 

Sequence created. 

IE緩存,沒有秩序。現在我們啓動兩場會議。我使用的是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. 

因此,在總結10萬單呼取 CACHE NOORDER =8秒 NOCACHE =8分鐘 CACHE ORDER =25秒

緩存秩序,Oracle並做RAC之間執行ping的很多節點,但它必須將內容寫回到seq $,直到緩存大小用完爲止,因爲它全部在內存中完成。

我會如果我是你,設置一個合適的緩存大小(ps高緩存大小不會把負載放在盒子內存,因爲oracle不會將所有數字存儲在RAM中;只有當前+最終號碼),並在需要時考慮訂單。

+0

謝謝,現在我有理由去「緩存和訂單」 –

+0

: - 我想知道你能告訴我什麼是設置緩存大小的參數。 –

+0

當然。這實際上也在我的樣本中。 '創建序列x從一個緩存n開始; '其中n是緩存大小(對於0,使用關鍵字nocache而不是緩存0) – DazzaL