Sidebar

La fragmentación a nivel de tabla es un tanto diferente, a la fragmentación de los índices...

Por: Carlos Contreras

Artículo sobre la fragmentación de índices

Si tuviésemos una tabla la cual fuera de puros inserts, tipo DatawareHose, donde casi no hay deletes y/o updates, no habría problema. Pero es muy raro este caso, ya que normalmente hay todo tipo de DML, no solamente inserts.

El problema es que si una tabla tiene 100 rows, actualizas las estadísticas, la famosa "marca de agua" o "high water mark" va a decir que tienes, por ejemplo 100 bloques usados (ojo, un row no necesariamente ocupa 1 bloque, pero para ejemplificar es más fácil así). Luego le borras 50 rows, actualizas estadísticas y Oracle te dirá que tienes ya sólo 50 registros, PERO siguen siendo 100 bloques usados, aunque no sea real!!!

Eso es la marca de Agua... se llama así, por la analogía de los contenedores de agua.. que cuando baja el nivel de agua, se nota ahí una ligera marca del nivel máximo de agua que llegó a tener.

Muchas veces Oracle tratará de usar esos huecos, para updates, etc.. pero la fragmentación en estos casos es prácticamente imposible de evitar...

Ahora... vamos a la acción!

Antes, en versiones anteriores a 10G, se solía hacer exportando la información, obtenías los permisos de la tabla, se borraba la misma y al final se importaba la información extraída y daban los permisos. Lo cual no necesariamente es un método malo.

También puedes hacer un alter a la tabla, como si fueses a moverla de tablespace, pero eligiendo el mismo de destino. Ojo con el espacio físico en este caso.

Para Oracle 10G:
Puedes hacer un alter a la tabla, con los parámetros "shrink space compact", sobre tablespaces con:

EXTENT MANAGEMENT=LOCAL
SEGMENT SPACE MANAGEMENT=AUTO

Si tu tablespace no tiene esas características, puedes obtener el siguiente error:

ORA-10635: Invalid segment or tablespace type

Una vez que hayas corroborado, que la tabla reside en un tablespace con esas caracs. Ahora sí, primero, habilita el row movement, sobre la tabla a desfragmentar.


SQL> alter table mi_tablaDBA enable row movement;


Ya que si no habilitas esto, obtendrás el siguiente error, al querer ejecutar el "shrink":

SQL> alter table mi_tablaDBA shrink space compact;


ORA-10636: ROW MOVEMENT is not enabled

Ahora sí, ejecuta lo siguiente:

SQL> alter table mi_tabla shrink space <compact>;


Si le quitas el compact, puede que sea más rápido tu defragmentación pero ocasionarás mas bloqueos. Por lo que para tablas grandes, no es lo mejor hacerlo en horas de operación.

Y listo!! Puedes revisar ahora las marcas de agua y verás que ya contienen los valores reales. Éstas las puedes ver en *_TABLES (*=user, all, dba) en el campo BLOCKS.

 

Carlos Contreras
DBA Support Europa.

Tips BD