# [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
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
    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
    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
    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
    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
    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
    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.
