En mi caso, trataré en este artículo una nueva funcionalidad incorporada en el último release de Oracle Database 18c.
Con la versión 18.1, se ha introducido una nueva
funcionalidad en la base de datos Oracle: Las "secuencias escalables” o en inglés "Scalable Sequences".
Se trata de la capacidad de poder crear secuencias
escalables para mejorar el rendimiento durante la carga masiva de datos, en
tablas que utilizan como claves el valor generado por una secuencia. Las
secuencias escalables optimizan el proceso de generación de valores
secuenciales mediante el uso de una combinación única del número de instancia y
el número de sesión para minimizar la contención sobre los bloques “leaf” en índices
durante cargas masivas. Esta es una de las pocas funciones que no es habilita
automáticamente y requiere la intervención del DBA para garantizar que su implementación
no afecte ni cambie la lógica de negocio necesaria.
Por su parte, desde el punto de vista de negocio, esta
funcionalidad brinda una mejora notable en los procesos de carga masiva de
datos al reducir, como comenté anteriormente, la contención generada al insertar
datos en tablas que utilizan valores de
secuencia.
Al incorporar la capacidad de poder crear valores de secuencias
con componente de instancia e identificadores de sesión agregados al valor propio
de la secuencia, la contención en la generación y en las inserciones en bloques de índice para
los valores clave, se reduce significativamente. Esto significa que Oracle
Database es aún más escalable para la carga de datos y puede admitir tasas de rendimiento
en este tipo de operaciones todavía más altas.
create /alter sequence nombre_de_secuencia scale [extend | noextend] | noscale
CREATE | ALTER SEQUENCE [ schema. ]sequence
[ { INCREMENT BY | START WITH } integer
| { MAXVALUE integer | NOMAXVALUE }
| { MINVALUE integer | NOMINVALUE }
| { CYCLE | NOCYCLE }
| { CACHE integer | NOCACHE }
| { ORDER | NOORDER }
| { SCALE {EXTEND | NOEXTEND} | NOSCALE}
[ { INCREMENT BY | START WITH } integer
| { MAXVALUE integer | NOMAXVALUE }
| { MINVALUE integer | NOMINVALUE }
| { CYCLE | NOCYCLE }
| { CACHE integer | NOCACHE }
| { ORDER | NOORDER }
| { SCALE {EXTEND | NOEXTEND} | NOSCALE}
SCALE / NOSCALE
Cuando se especifica la opción SCALE, se establece un prefijo numérico al comienzo
de la secuencia (por defecto de 6 dígitos) con el formato:
[ iii || sss || ... ]
En donde "iii" determina un offset de 3 dígitos, correspondiente
al id de instancia, dado por [(id de instancia% 100) + 100] y "sss" es un offset, también de tres dígitos, correspondiente al ID de sesión, dado en este caso por [id de sesión% 1000].
Finalmente “||” es el operador de concatenación usado entre iii,sss y el valor de la
secuencia.
Resumiendo entonces, de los 6 dígitos usados por el offset, tres dígitos corresponden al número de
instancia y tres al ID de sesión.
EXTEND/NOEXTEND
Cuando se especifica EXTEND junto a la palabra clave SCALE,
los valores de secuencia generados son todos de longitud (x + y), donde “x” es
la longitud del desplazamiento escalable (valor predeterminado 6), e “y”es el
número máximo de dígitos en la secuencia acorde al valor máximo. Por lo tanto,
para una secuencia ascendente con un valor máximo de 100 y SCALABLE EXTEND especificados, los valores de secuencia generados son de
la forma:
iii || sss || 001, iii || sss || 002,…, iii || sss || 100
iii || sss || 001, iii || sss || 002,…, iii || sss || 100
La configuración predeterminada para la cláusula SCALE es
NOEXTEND. Con la configuración NOEXTEND, los valores de secuencia generados son
a lo sumo tan anchos como el número máximo de dígitos en la secuencia maxvalue/minvalue. La base de datos agrega la escala de 6 dígitos en la parte superior del dígito
para el valor máximo. Esta configuración es útil para la integración con
aplicaciones existentes donde las secuencias se utilizan para rellenar columnas
de ancho fijo. Al invocar NEXTVAL en una secuencia con SCALABLE NOEXTEND
especificado, se genera un error de usuario si el valor generado requiere más
dígitos de representación que el valor máximo/mínimo de la secuencia.
La adición de 100 en la generación iii garantiza que todos
los valores generados tengan la misma longitud y, por lo tanto, no habrá
duplicados en los valores generados en todas las instancias.
La longitud predeterminada del desplazamiento de secuencia
escalable es 6.
Así que en el siguiente ejemplo, la secuencia escalable será
de 13 dígitos (número de desplazamiento escalable de 6 dígitos + valor máximo
de 7 dígitos)
Algunos ejemplos:
Datos de la sesión que usaremos:
SQL> select instance_number from v$instance;
INSTANCE_NUMBER
---------------
1
---------------
1
SQL> select sys_context('userenv','sid')
from dual;
SYS_CONTEXT('USERENV','SID')
---------------------------------------------
34
---------------------------------------------
34
Creamos una secuencia estándar:
SQL> create sequence tst_sequence;
Sequence created.
Verificamos que no tiene habilitadas las opciones SCALE y EXTEND:
SQL> select sequence_name, scale_flag, extend_flag from user_sequences;
SEQUENCE_NAME S E
------------- -- --
TST_SEQUENCE N N
Creamos ahora la secuencia con máximo default (9999999999999999999999999999-28
digitos) y SCALE habilitado pero no EXTEND
SQL> create sequence tst_sequence scale;
Sequence created.
Verificamos:
SQL> select sequence_name,max_value,scale_flag, extend_flag from
user_sequences;
SEQUENCE_NAME MAX_VALUE S E
------------- ---------------------------
-- --
TST_SEQUENCE 9999999999999999999999999999 Y N
Al no estar habilitado EXTEND utiliza SCALE iii/sss en la parte superior
del máximo (28 digitos)
SQL> select tst_sequence.nextval from dual;
NEXTVAL
----------------------------
1010340000000000000000000001
Creamos ahora la secuencia con maxvalue en 9999999(7 digitos) y scale extend
habilitado:
SQL> create sequence test_seq maxvalue 9999999 scale extend;
Sequence created.
El numero de secuencia es entonces 0000001 y se agrega en la parte
superior los 6 digitos correspondientes a sesión 034 e instancia
101(instance_id + 100)
SQL> select test_seq.nextval from dual;
NEXTVAL
-------------
1010340000001
En el siguiente caso, el maxvalue es 9999999, scale y extend
habilitado.
SQL> create sequence test_seq maxvalue 9999999 scale extend;
Sequence created.
Al
estar habilitado EXTEND se adiciona a los 3 digitos del maxvalue(100)el numero
de sesión e instancia.
SQL> select test_seq.nextval from dual;
NEXTVAL
-----------
1010340000001
Si por el contrario se especifica
NOEXTEND, el offset de instancia (iii) y sesión (sss) van a ser contemplado en
el maxvalue que es de 100(3 digitos) por lo tanto nos va a devolver un error:
SQL> create sequence seq_noextend
start with 1 increment by 1 minvalue 1 maxvalue 100 scale noextend;
Sequence created.
SQL> select seq_noextend.nextval
from dual;
select seq_noextend.nextval from dual
*
ERROR at line 1:
ORA-64603: NEXTVAL cannot be instantiated for SEQ_NOEXTEND. Widen the sequence by 4 digits or alter sequence with SCALE EXTEND.
select seq_noextend.nextval from dual
*
ERROR at line 1:
ORA-64603: NEXTVAL cannot be instantiated for SEQ_NOEXTEND. Widen the sequence by 4 digits or alter sequence with SCALE EXTEND.
En este caso, creamos la secuencia con un máximo de 9999999
(7 digitos) como indicamos extent a scale
Se puede realizar un alter de las cláusulas “extend” y “noextend”
y también de puede cambiar una secuencia escalable a secuencia normal y
viceversa.
Oracle recomienda que no especifique ordenamiento para una secuencia escalable, ya que los
números de secuencia escalables están desordenados a nivel global.
SQL> alter sequence test_seq maxvalue 9999999 scale
noextend;
Sequence altered.
SQL> alter sequence test_seq maxvalue 9999999 noscale;
Sequence altered.
SQL> alter sequence test_seq maxvalue 9999999 scale;
Sequence altered.
Espero les resulte interesante.
No hay comentarios:
Publicar un comentario