Oracle
 sql >> Database >  >> RDS >> Oracle

I valori Oracle Sequence non sono ordinati

In secondo luogo, posso ottenere l'ordine se modifico la sequenza in beNOCACHE indipendentemente da ORDER/NOORDER.

sì perché NOCACHE è effettivamente ordinato poiché stai forzando una scrittura nella tabella sys.seq$ su ogni incremento, che deve essere serializzato anche sui nodi.

--

Contesterei la risposta accettata in quel possibile duplicato. c'è un'enorme differenza in CACHE + ORDER e NOCACHE in RAC. Non stai annullando la CACHE con ORDINE; solo riducendone l'efficacia. Personalmente ho visto le prestazioni di un'applicazione di livello intermedio peggiorare drasticamente poiché utilizzavano NOCACHE su una sequenza e accedevano a più nodi contemporaneamente. Abbiamo cambiato la loro sequenza in ORDER CACHE (poiché volevano un ordine incrociato). e le prestazioni sono nettamente migliorate.

in sintesi:La velocità della sequenza sarà dalla più veloce alla più lenta come "CACHE NOORDER"->"CACHE ORDER" e molto indietro rispetto a "NOCACHE".

Anche questo è facilmente verificabile:

Quindi iniziamo con una sequenza standard:

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

Sequence created.

cioè CACHE senza ordine. Ora avviamo due sessioni. Sto usando un database RAC a 4 nodi 10.2.0.4 in questo test:

il mio script di prova è semplicemente

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

ora eseguiamo il primo 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.

quindi 7-8 secondi per selezionare 100.000 iterazioni della sequenza.

Ora proviamo NOCACHE (ORDER vs NOORDER è irrilevante per questo, poiché stiamo forzando una scrittura su seq$ per ogni chiamata alla sequenza).

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.

quindi siamo passati da 8 secondi a 8 MINUTI per lo stesso set di lavoro.

che dire di CACHE + ORDINE?

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.

quindi in sintesi per 100.000 recuperi in chiamata singolaCACHE NOORDER =8 secondiNOCACHE =8 minutiCACHE ORDER =25 secondi

per l'ordine della cache, Oracle esegue molti ping tra i nodi RAC, ma NON devo riscrivere le cose su seq$ fino a quando la dimensione della cache non è esaurita, poiché è tutto fatto in memoria.

se fossi in te, imposti una dimensione della cache appropriata (p.s. una dimensione della cache elevata non carica la memoria della scatola, poiché Oracle non memorizza tutti i numeri nella RAM; solo il numero corrente + finale) e considera ORDINA se necessario.