En las versiones anteriores a la release 2 de la base de datos Oracle 11g, cuando se creaba cualquier objeto en la base de datos utilizando una sentencia SQL o PL/SQL, ya fuera un tabla, un índice o cualquier otro objeto que requiriese ser almacenado, el gestor de la base de datos creaba los segmentos necesarios y asignaba un tamaño inicial a los mismos, un tamaño que podía ser pequeño, de unos 64 Kbytes mínimo, pero dicho espacio ya no podía ser utilizado para otras necesidades. En los tiempos actuales, un tamaño de 64 Kbytes no es nada, pero si algo tan pequeño se tienen que repetir muchas veces, entonces el consumo de recursos de almacenamiento puede llegar a ser bastante grande.
Por ejemplo, podemos pensar en alguna aplicación que necesitase crear cientos o miles de tablas, tablas que nunca van a ser utilizadas pero cuyos segmentos de almacenamiento tienen que ser creados de todas formas. Algunos pueden preguntarse por qué un aplicación puede necesitar crear tablas que nunca van a ser utilizadas, este hecho no es tan extraño ya que existen muchas aplicaciones, como por ejemplo Oracle Financials, que ofrecen funcionalidades que requieren el uso de determinadas tablas y dichas tablas sólo contienen datos cuando se hace uso de dichas funcionalidades. Para evitar el consumo de almacenamiento en este tipo de situaciones, la release 2 de la base de datos Oracle 11g incorpora una nueva funcionalidad conocida como creación diferida de segmentos (Deferred Segment Creation), funcionalidad que a continuación explicaremos y analizaremos.
La funcionalidad de creación diferida de segmentos puede establecerse a nivel de sistema, a nivel de sesión, o incluso a nivel de sentencia SQL DDL. Veamos a continuación los diferentes comandos SQL que permiten realizar este cambio:
ALTER SYSTEM SET deferred_segment_creation=true; ALTER SESSION SET deferred_segment_creation=true; CREATE TABLE table_name .................... SEGMENT CREATION DEFERRED;
Obviamente el parámetro deferred_segment_creation puede inicializarse desde el fichero init.ora y, por defecto, es decir, si no se le asigna un valor en concreto en dicho fichero, tomará el valor de true, por lo que la funcionalidad de creación diferida de segmentos estará habilitada a menos que hayamos decidido cambiar el valor de dicho parámetro a false.
Por otro lado, también conviene mencionar que es posible forzar la creación de los segmentos a nivel de sentencia SQL utilizando la cláusula SEGMENT CREATION IMMEDIATE.
Por lo tanto, cuando la funcionalidad de creación diferida de segmentos está habilitada, una tabla de la base de datos Oracle no consumirá recursos de almacenamiento hasta que se inserta el primer registro en dicha tabla, esto es también extensible a cualquier índice u objeto que esté asociado con dicha tabla.
Con la release 2 de la base de datos Oracle 11g, la tabla del sistema USER_TABLES incorpora un nuevo campo denominado SEGMENT_CREATED, campo que tomará el valor de NO en el momento de la creación de una tabla siempre que hayamos utilizado la cláusula SEGMENT CREATION DEFERRED o que el parámetro deferred_segment_creation tenga el valor de true. Sólo en el instante en que se inserte el primer registro en dicha tabla, el mencionado campo SEGMENT_CREATED pasará a tomar el valor de YES.
Otras tablas del sistema que pueden ser útiles para verificar la utilización de segmentos de almacenamiento son USER_EXTENTS y USER_SEGMENTS, ambas tablas muestran información muy similar por lo que en el siguiente ejemplo sólo utilizaré una de ellas.
SQL> CREATE TABLE p1 ( a INT CONSTRAINT p1_pk PRIMARY KEY, b INT CONSTRAINT p1_b UNIQUE, c CLOB ) LOB (c) STORED AS p1_c SEGMENT CREATION DEFERRED; Table created. SQL> SELECT segment_created FROM user_tables WHERE table_name = 'P1'; SEGMENT_CREATED --------------- NO 1 row selected. SQL> SELECT segment_name, segment_type, bytes FROM user_segments WHERE segment_name like 'P1%'; no rows selected.
Con el comando SQL CREATE TABLE, que incorpora la cláusula SEGMENT CREATION DEFERRED, hemos creado la tabla P1. Después, la información que devuelven las sentencias SELECT nos demuestra que los segmentos de almacenamiento no han sido creados todavía.
Sigamos con el ejemplo.
SQL> INSERT INTO p1 VALUES (1,2,'Prueba PLSQL'); 1 row created. SQL> SELECT segment_created FROM user_tables WHERE table_name = 'P1'; SEGMENT_CREATED --------------- YES 1 row selected. SQL> SELECT segment_name, segment_type, bytes FROM user_segments WHERE segment_name like 'P1%'; SEGMENT_NAME SEGMENT_TYPE BYTES ------------ ------------ ----- P1 TABLE 65536 P1_PK INDEX 65536 P1_B INDEX 65536 P1_C LOBSEGMENT 65536 4 rows selected.
Una vez que se inserta un registro en la tabla P1, las mismas sentencias SELECT que hemos utilizado anteriormente indican que ya se están consumiendo recursos de almacenamiento, y, en concreto, en la tabla USER_SEGMENTS, aparecen todos los objetos asociados con la tabla P1 que consumen recursos de este tipo.
2 comentarios:
Exclente tu explicación del comando y el parametro, de gran utilidad gracias.
Gracias Derwin, comentarios como el tuyo me animan a continuar escribiendo artículos sobre PL/SQL y bases de datos Oracle.
Publicar un comentario