[23ai] Deferred Segment Creation


En Oracle existe el parámetro deferred_segment_creation, que permite la creación diferida de segmentos en la base de datos. Este parámetro ya existía en versiones anteriores, lleva con nosotros desde la versión Oracle 11G R2. Además, cabe resaltar que se puede modificar a nivel de PDB, dándonos una mayor flexibilidad a la hora de administrar nuestras CDB.
SQL> show parameter DEFERRED_SEGMENT_CREATION
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
deferred_segment_creation boolean TRUE
Pero ¿qué funcionalidad tiene? La mejor manera de ver su funcionalidad es viendo los posibles valores que puede tomar, estos valores son los siguientes:
TRUE: Los segmentos a nivel de tabla así como sus dependencias, como pueden ser LOBs o índices, se crean de manera diferida al insertar la primera fila. Esto nos da ciertas ventajas como puede ser la gestión eficiente de espacio ya que evitamos la creación de segmentos vacíos.
Veamos un ejemplo. Tengo una PDB donde el valor del parámetro es TRUE
SQL> show con_name; CON_NAME ------------------------------ FREEPDB1 SQL> show parameter DEFERRED_SEGMENT_CREATION NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ deferred_segment_creation boolean TRUE
Vamos a definir una tabla dentro del schema HR y vemos si se han creado sus segmentos.
SQL> conn hr/xxxxxx SQL> Create Table t_test_segment ( col_1 number generated by default as identity, col_2 varchar2(10) ); Table created. SQL> Select Segment_Name, Segment_Type From user_Segments Where Segment_Name = 'T_TEST_SEGMENT'; no rows selected
Al definir la tabla no se ha creado automáticamente los segmentos al tener seteado el parámetro a TRUE. Vamos insertar una fila y verificamos los segmentos.
SQL> Insert into t_test_Segment (col_2 ) Values ( 'David' ); 1 row created. SQL> commit; Commit complete. SQL> Select Segment_Name, Segment_Type From user_Segments Where Segment_Name = 'T_TEST_SEGMENT'; SEGMENT_NAME SEGMENT_TYPE -------------------- -------------------- T_TEST_SEGMENT TABLE
Correcto, el segmento se ha creado en el momento que se ha insertado la fila en nuestra tabla, pero y si el usuario es SYS ¿el funcionamiento sería el mismo?
SQL> conn sys/xxxxx as sysdba SQL> Create Table t_test_segment_SYS ( col_1 number generated by default as identity, col_2 varchar2(10)); Table created. SQL> Select Segment_Name, Segment_Type From user_Segments Where Segment_Name = 'T_TEST_SEGMENT_SYS'; SEGMENT_NAME SEGMENT_TYPE -------------------- -------------------- T_TEST_SEGMENT_SYS TABLE
La respuesta es NO. Solo hemos creado la tabla y el segmento se ha creado. Esto se debe a las restricciones asociadas con el parámetro:
El parámetro no es compatible con ciertos tipos de tablas dentro de los schemas: SYS, SYSTEM, PUBLIC, OUTLN o XDB.
Estos tipos son:
Clustered tables
Global temporary tables
Session-specific temporary tables
Internal tables
External tables.
No es soportado en el tablespace SYSTEM, lo que significa que cualquier tabla creada en este tablespace generará segmentos de inmediato.
Transacciones serializables.
FALSE: Los segmentos a nivel de tabla así como sus dependencias, como pueden ser LOBs o índices, se crean de manera inmediata.
Vamos a definir una tabla dentro del schema HR y vemos si se han creado sus segmentos. Pero antes de eso, vamos a cambiar el parámetro a nivel de PDB.
SQL> alter system set deferred_segment_creation = false scope=spfile; SQL> shu immediate Pluggable Database closed. SQL> startup Pluggable Database opened. SQL> show parameter deferred_segment_creation NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ deferred_segment_creation boolean FALSE
Definimos la tabla y verificamos que el segmento se crea automáticamente.
SQL> conn hr/oracle Connected. SQL> Create Table t_test_segment_FALSE ( col_1 number generated by default as identity, col_2 varchar2(10)); Table created. SQL> Select Segment_Name, Segment_Type From user_Segments Where Segment_Name = 'T_TEST_SEGMENT_FALSE'; SEGMENT_NAME SEGMENT_TYPE -------------------- ------------------ T_TEST_SEGMENT_FALSE TABLE
El segmento se creo automáticamente.
Espero que os sirva.
Subscribe to my newsletter
Read articles from David Sanz directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

David Sanz
David Sanz
Soy desarrollador, Analista, DBA Oracle y Arquitecto OCI, certificado en OCI Migration and Integration Certified Professional y Certified Architect Associate con más de 15 años de experiencia en plataformas Oracle además de especialista en temas de rendimiento.