Disponível a partir do Oracle Database 12c Release 1 (12.1.0.1), temos a opção de fazer uso de uma nova funcionalidade, sequence "temporária" ou sequence a nível de sessão do usuário.
O objeto session sequence é um tipo especial de seqüência especificamente projetado para ser usado com tabelas temporárias globais que tenham visibilidade da sessão.
Este tipo de sequence é voltado para tabelas temporárias, pois, os dados gerados pela sequence existem apenas a nível de sessão do usuário, reiniciando seu contador a cada vez que a sessão é reiniciada.
O padrão para criação de uma sequence é como demonstrado abaixo. Este modo de criação é o modo: "global", e é o default para criação de uma sequence.
Você tem opção de especificar GLOBAL junto ao create da sequence caso queira, ou simplesmente omitir esta opção que por padrão já será o modo GLOBAL.
CREATE SEQUENCE customers_seq START WITH 1000 INCREMENT BY 1 NOCACHE NOCYCLE;
Especifique SESSION para criar uma sequence de sessão. Ao contrário das sequências regulares existentes (referidas como sequências "globais"), uma sequence de sessão retorna uma gama única de números de seqüências apenas dentro de uma sessão, mas não em sessões.
Outra diferença é que as sequências de sessão não são persistentes. Se uma sessão desaparecer, o mesmo acontece com o estado das sequências de sessão acessadas durante a sessão.
Embora o objeto session sequence ser projetado para ser usado com tabelas temporárias globais, ou a nível de sessão, vamos a um exemplo com tabela temporária a nível de "COMMIT":
Vamos lá!
Vamos nos conectar ao banco de dados com um usuário que já tinhamos criado: user01:
[oracle@serv01 ~]$ sqlplus user01/teste SQL*Plus: Release 12.1.0.2.0 Production on Thu Feb 15 18:55:06 2018 Copyright (c) 1982, 2014, Oracle. All rights reserved. Last Successful login time: Thu Feb 15 2018 18:39:12 -02:00 Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Agora crie nossa tabela temporária: tmp_teste01, a nível de COMMIT:
SQL> create global temporary table tmp_teste01 ( id number )on commit delete rows; Table created.
Certo. Para nossos testes vamos criar duas sequences, uma global que é o padrão já conhecido, que costumamos criar, com nome: seq_global. Esta sequence utilizaremos no final do artigo para um teste de performance.
A outra sequence, será a session sequence com nome: seq_sess_temp, veja abaixo:
SQL> create sequence seq_global global
start with 1
increment by 1;
Sequence created.
SQL>
SQL> create sequence seq_sess_temp session
start with 1
increment by 1;
Sequence created.
SQL>
Veja abaixo que as sequences estão presentes no dicionário de dados:
Repare o flag: session_flag. Ele Indica se os valores de seqüência são referente a sessão privada: (Y) ou não (N).
É importante entender que quando falamos de session sequence, o que é temporário é os dados que são gerados por ela e não o objeto sequence.
SQL> col sequence_name format a20 col last_number format 9999 col session_flag format a2 select s.sequence_name, s.last_number, s.session_flag from user_sequences s where s.sequence_name IN('SEQ_SESS_TEMP','SEQ_GLOBAL'); SEQUENCE_NAME LAST_NUMBER SE -------------------- ----------- -- SEQ_GLOBAL 1 N SEQ_SESS_TEMP 1 Y SQL>
Agora vamos inserir cinquenta registros em nossa tabela temporária utilizando nossa sequence a nível de sessão, e posteriormente consultar os dados inseridos na tabela temporária:
SQL> begin for x in 1 .. 50 loop insert into tmp_teste01 values (seq_sess_temp.nextval); end loop; end; / PL/SQL procedure successfully completed. SQL> select * from tmp_teste01; ID ---------- 1 2 3 4 5 6 7 8 9 10 11 ID ---------- 12 13 14 15 16 17 18 19 20 21 22 ID ---------- 23 24 25 26 27 28 29 30 31 32 33 ID ---------- 34 35 36 37 38 39 40 41 42 43 44 ID ---------- 45 46 47 48 49 50 50 rows selected.
Ok, confirme a transação com COMMIT e os dados serão desconsiderados em nossa tabela temporária como abaixo:
SQL> commit; Commit complete. SQL> select * from tmp_teste01; no rows selected
Continuando, insira novamente os dados e consulte os dados inseridos.
Repare que o contador da sequence não foi desconsiderado e reiniciado sua numeração para iniciar em 1, pois, esta sequence trabalha com duração do tempo de vida da sessão do usuário, ou a nível de sessão e não a nível de transação. Ou seja, se desconectarmos nossa sessão, os dados gerados pela sequence serão desconsiderados.
SQL> begin for x in 1 .. 50 loop insert into tmp_teste01 values (seq_sess_temp.nextval); end loop; end; / PL/SQL procedure successfully completed. SQL> select * from tmp_teste01; ID ---------- 51 52 53 54 55 56 57 58 59 60 61 ID ---------- 62 63 64 65 66 67 68 69 70 71 72 ID ---------- 73 74 75 76 77 78 79 80 81 82 83 ID ---------- 84 85 86 87 88 89 90 91 92 93 94 ID ---------- 95 96 97 98 99 100 50 rows selected. SQL> SQL> commit; Commit complete. SQL> select * from tmp_teste01; no rows selected SQL>
Agora, desconecte e conecte novamente no banco de dados Oracle com nosso user01:
SQL> discon Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options SQL> exit [oracle@serv01 ~]$ sqlplus user01/teste SQL*Plus: Release 12.1.0.2.0 Production on Fri Feb 16 12:36:34 2018 Copyright (c) 1982, 2014, Oracle. All rights reserved. Last Successful login time: Fri Feb 16 2018 08:58:42 -02:00 Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options SQL>
Popule novamente nossa tabela temporária e repare que a sequencia voltou a contar a partir do número 1:
SQL> begin for x in 1 .. 50 loop insert into tmp_teste01 values (seq_sess_temp.nextval); end loop; end; / PL/SQL procedure successfully completed. SQL> select * from tmp_teste01; ID ---------- 1 2 3 4 5 6 7 8 9 10 11 ID ---------- 12 13 14 15 16 17 18 19 20 21 22 ID ---------- 23 24 25 26 27 28 29 30 31 32 33 ID ---------- 34 35 36 37 38 39 40 41 42 43 44 ID ---------- 45 46 47 48 49 50 50 rows selected.
Teste de Performance:
Vamos fazer agora um pequeno teste de performance entre os dois tipos de sequences ( Global e SESSION ).
Lembrando que cada tipo de sequence foi projetada para cenários ou usos específicos, então cabe analisar a sequence ideal para o modelo de negócio ideal.
[oracle@serv01 ~]$ sqlplus user01/teste SQL*Plus: Release 12.1.0.2.0 Production on Fri Feb 16 12:51:58 2018 Copyright (c) 1982, 2014, Oracle. All rights reserved. Last Successful login time: Fri Feb 16 2018 12:41:36 -02:00 Connected to: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Certo, vamos fazer um teste, vamos executar um loop com dez mil iterações, obtendo o valor sequêncial das nossas duas sequences(GLOBAL e SESSION).
Vamos computar o tempo inicial e final de processamento e ver qual foi mais rápida entre as iterações:
SQL> SET SERVEROUTPUT ON SQL> DECLARE 2 vInicio NUMBER; 3 vValor_sequence NUMBER; 4 BEGIN 5 vInicio := DBMS_UTILITY.get_time; 6 7 FOR i IN 1 .. 10000 LOOP 8 vValor_sequence := seq_global.NEXTVAL; 9 END LOOP; 10 11 DBMS_OUTPUT.put_line('Global Sequence : ' || (DBMS_UTILITY.get_time - vInicio) || ' hsecs'); 12 13 vInicio := DBMS_UTILITY.get_time; 14 15 FOR i IN 1 .. 10000 LOOP 16 vValor_sequence := seq_sess_temp.NEXTVAL; 17 END LOOP; 18 19 DBMS_OUTPUT.put_line('Session Sequence: ' || (DBMS_UTILITY.get_time - vInicio) || ' hsecs'); 20 END; 21 / Global Sequence : 17 hsecs Session Sequence: 11 hsecs PL/SQL procedure successfully completed. SQL>
Podemos ver que a sequence a nível de sessão(SESSION) foi bem mais rápida que a sequence GLOBAL. Mas, cada caso é um caso! Cada sequence para seu modelo de negócio.
É isso pessoal,
Abraço,
Ronaldo.
Nenhum comentário:
Postar um comentário