Oracle
 sql >> Base de données >  >> RDS >> Oracle

La valeur de séquence Oracle n'est pas ordonnée

Deuxièmement, puis-je réaliser la commande si je modifie la séquence en NOCACHE indépendamment de ORDER/NOORDER.

oui car NOCACHE est effectivement commandé car vous forcez une écriture dans la table sys.seq$ à chaque incrément, qui doit également sérialiser sur les nœuds.

--

Je contesterais la réponse acceptée dans ce double possible. il y a une énorme différence entre CACHE + ORDER et NOCACHE dans RAC. Vous n'êtes pas en train de nier le CACHE avec ORDER ; ne fait que réduire son efficacité. J'ai personnellement vu les performances d'une application de niveau intermédiaire se dégrader considérablement lorsqu'elle utilisait NOCACHE sur une séquence et accédait à plusieurs nœuds à la fois. Nous avons changé leur séquence en ORDER CACHE (car ils voulaient une commande cross-rac). et les performances considérablement améliorées.

en résumé:La vitesse de la séquence sera du plus rapide au plus lent comme "CACHE NOORDER"->"CACHE ORDER" et bien loin derrière "NOCACHE".

Ceci est également facilement testable :

Nous commençons donc avec une séquence standard :

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

Sequence created.

c'est-à-dire CACHE sans commande. Maintenant, nous lançons deux sessions. J'utilise une base de données RAC à 4 nœuds 10.2.0.4 dans ce test :

mon script de test est simplement

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

maintenant on lance le premier test (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.

donc 7-8 secondes pour sélectionner 100 000 itérations de la séquence.

Essayons maintenant NOCACHE (ORDER vs NOORDER n'est pas pertinent pour cela, car nous forçons une écriture dans seq$ pour chaque appel à la séquence).

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.

nous sommes donc passés de 8 secondes à 8 MINUTES pour le même ensemble de travail.

qu'en est-il du CACHE + COMMANDE ?

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.

donc en résumé pour 100 000 extractions d'appel uniqueCACHE NOORDER =8 secondesNOCACHE =8 minutesCACHE ORDER =25 secondes

pour l'ordre du cache, oracle fait beaucoup de ping entre les nœuds RAC, mais il NE PAS doivent réécrire des choses dans seq$ jusqu'à ce que la taille du cache soit épuisée, car tout est fait en mémoire.

je le ferais si j'étais vous, définissez une taille de cache appropriée (p.s. une taille de cache élevée ne charge pas la mémoire de la boîte, car oracle ne stocke pas tous les nombres dans la RAM; seulement le nombre actuel + final) et considérez COMMANDER si besoin.