Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle-Sequenzwerte sind nicht geordnet

Zweitens:Kann ich die Reihenfolge erreichen, wenn ich die Sequenz zu beNOCACHE ändere, unabhängig von ORDER/NOORDER.

Ja, denn NOCACHE ist effektiv eine Reihenfolge, da Sie bei jedem Inkrement einen Schreibvorgang in die Tabelle sys.seq$ erzwingen, der auch über Knoten serialisiert werden muss.

--

Ich würde die akzeptierte Antwort in diesem möglichen Duplikat bestreiten. Es gibt einen großen Unterschied zwischen CACHE + ORDER und NOCACHE in RAC. Sie negieren den CACHE nicht mit ORDER; reduziert nur seine Wirksamkeit. Ich persönlich habe gesehen, wie sich die Leistung einer Anwendung der mittleren Ebene drastisch verschlechtert hat, als sie NOCACHE für eine Sequenz verwendet haben und auf mehrere Knoten gleichzeitig zugegriffen haben. Wir haben ihre Sequenz auf ORDER CACHE umgestellt (da sie eine Cross-Rac-Order wollten). und Leistung drastisch verbessert.

Zusammenfassend:Die Sequenzgeschwindigkeit wird vom schnellsten zum langsamsten als "CACHE NOORDER" -> "CACHE ORDER" und weit weit hinter "NOCACHE" liegen.

Dies ist auch leicht testbar:

Wir beginnen also mit einer Standardsequenz:

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

Sequence created.

dh CACHE ohne Auftrag. Jetzt starten wir zwei Sessions. Ich verwende in diesem Test eine 4-Knoten-RAC-Datenbank 10.2.0.4:

Mein Testskript ist einfach

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;                                                   
/ 
/

Jetzt führen wir den ersten Test durch (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.

also 7-8 Sekunden, um 100.000 Iterationen der Sequenz auszuwählen.

Versuchen wir es jetzt mit NOCACHE (ORDER vs. NOORDER ist dafür irrelevant, da wir für jeden Aufruf der Sequenz einen Schreibvorgang in seq$ erzwingen).

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.

also sind wir für denselben Arbeitssatz von 8 Sekunden auf 8 MINUTEN gesprungen.

Was ist mit 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.

also zusammenfassend für 100.000 einzelne AnrufabrufeCACHE NOORDER =8 SekundenNOCACHE =8 MinutenCACHE ORDER =25 Sekunden

Für die Cache-Reihenfolge pingt Oracle viel zwischen den RAC-Knoten, aber es TUT NICHT müssen Sachen in seq$ zurückschreiben, bis die Cache-Größe aufgebraucht ist, da alles im Speicher erledigt wird.

Ich würde an deiner Stelle eine angemessene Cache-Größe einstellen (p.s. eine hohe Cache-Größe belastet den Speicher der Box nicht, da Oracle nicht alle Zahlen im RAM speichert; nur die aktuelle + letzte Zahl) und überlege BESTELLEN Sie ggf.