Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

O valor da Sequência Oracle não está ordenado


Em segundo lugar, posso conseguir a ordenação se alterar a sequência para serNOCACHE independentemente de ORDER/NOORDER.

sim, pois NOCACHE é efetivamente ordenado, pois você está forçando uma gravação na tabela sys.seq$ em cada incremento, que também precisa serializar nos nós.

--

Eu contestaria a resposta aceita nessa possível duplicata. existe uma diferença enorme no CACHE + ORDER e NOCACHE no RAC. Você não está negando o CACHE com ORDER; apenas reduzindo sua eficácia. Eu pessoalmente vi o desempenho de um aplicativo de camada intermediária degradar drasticamente, pois eles usaram NOCACHE em uma sequência e estavam acessando vários nós ao mesmo tempo. Mudamos a sequência deles para ORDER CACHE (pois eles queriam uma ordem cross-rac). e o desempenho melhorou drasticamente.

em resumo:A velocidade da sequência será do mais rápido para o mais lento como "CACHE NOORDER"->"CACHE ORDER" e muito atrás de "NOCACHE".

Isso também é facilmente testável:

Então começamos com uma sequência padrão:
SQL> create sequence daz_test start with 1 increment by 1 cache 100 noorder;

Sequence created.

ou seja, CACHE sem ordem. Agora iniciamos duas sessões. Estou usando um banco de dados RAC de 4 nós 10.2.0.4 neste teste:

meu script de teste é simplesmente
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;                                                   
/ 
/

agora executamos o primeiro teste (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.

então 7-8 segundos para selecionar 100.000 iterações da sequência.

Agora vamos tentar NOCACHE (ORDER vs NOORDER é irrelevante para isso, pois estamos forçando uma gravação para seq$ para cada chamada para a sequência).
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.

então saltamos de 8 segundos para 8 MINUTOS para o mesmo conjunto de trabalho.

e CACHE + ORDEM?
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.

então, em resumo, para 100.000 chamadas únicas fetchesCACHE NOORDER =8 segundosNOCACHE =8 minutosCACHE ORDER =25 segundos

para ordem de cache, o Oracle faz muito ping entre os nós RAC, mas NÃO tem que escrever coisas de volta para seq$ até que o tamanho do cache seja usado, pois tudo é feito na memória.

eu faria se eu fosse você, defina um tamanho de cache apropriado (p.s. um tamanho de cache alto não sobrecarrega a memória da caixa, pois o oracle não armazena todos os números na RAM; apenas o número atual + final) e considere ORDEM se necessário.