Las tablas con objetos BLOB en tablespaces diferentes del resto de la tabla, tienen un tratamiento algo diferente.
Vamos a preparar un entorno de pruebas:
Creamos 2 tablespaces con:
CREATE SMALLFILE TABLESPACE "TS_PFIRMA_DATOS" LOGGING DATAFILE '/u01/app/oracle/oradata/PRUEBA/TS_PFIRMA_DATOS.dbf' SIZE 10M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
CREATE SMALLFILE TABLESPACE "TS_PFIRMA_BLOB" LOGGING DATAFILE '/u01/app/oracle/oradata/PRUEBA/TS_PFIRMA_BLOB.dbf' SIZE 10M EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
La tabla:
CREATE TABLE "SCOTT"."PF_ARC"
(
"is" NUMBER(10,0) NOT NULL ENABLE,
"B_ARCHIVO" BLOB
)
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING STORAGE
(
INITIAL 100000 NEXT 100000 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT
)
TABLESPACE "TS_PFIRMA_DATOS" LOB
(
"B_ARCHIVO"
)
STORE AS
(
TABLESPACE "TS_PFIRMA_BLOB" DISABLE STORAGE IN ROW CHUNK 32768 PCTVERSION 10 NOCACHE LOGGING STORAGE(INITIAL 100000 NEXT 100000 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
) ;
Si añadimos unos registros en esta tabla podemos ver la ocupación real del campo BLOB con:
SQL> SELECT sum(dbms_lob.getlength(s.B_ARCHIVO)) FROM SCOTT.PF_ARC s;
SUM(DBMS_LOB.GETLENGTH(S.B_ARCHIVO))
------------------------------------
5441368
Con el número de extensiones:
SQL> SELECT e.owner, e.segment_name,e.segment_type, count(*) FROM dba_extents e WHERE e.TABLESPACE_NAME='TS_PFIRMA_BLOB' GROUP BY e.owner, e.segment_name,e.segment_type;
OWNER SEGMENT_NAME SEGMENT_TYPE COUNT(*)
------------------------------ ------------------------------------------------------------------------- ------------------------ --------------
SCOTT SYS_LOB0000052624C00002$$ LOBSEGMENT 21
SCOTT SYS_IL0000052624C00002$$ LOBINDEX 1
Si se eliminan registros se se puede ver que el cambio es reflejado en el tamaño real del campo BLOB:
SQL> SELECT sum(dbms_lob.getlength(s.B_ARCHIVO)) FROM SCOTT.PF_ARC s;
SUM(DBMS_LOB.GETLENGTH(S.B_ARCHIVO))
------------------------------------
171349
Aunque el número de extensiones sigue igual, el tablespace no libera espacio esto se puede solucionar con:
ALTER TABLE scott.PF_ARC enable row movement;
ALTER TABLE scott.PF_ARC shrink space cascade;
Una vez ejecutado esto las extensiones son liberadas:
SQL> SELECT e.owner, e.segment_name,e.segment_type, count(*) FROM dba_extents e WHERE e.TABLESPACE_NAME='TS_PFIRMA_BLOB' GROUP BY e.owner, e.segment_name,e.segment_type;
OWNER SEGMENT_NAME SEGMENT_TYPE COUNT(*)
------------------------------ ------------------------------------------------------------------------- ------------------------ --------------
SCOTT SYS_LOB0000052624C00002$$ LOBSEGMENT 8
SCOTT SYS_IL0000052624C00002$$ LOBINDEX 1
Como en cualquier compactación, es necesario realizar una reconstrucción de todos los índices relacionados con la tabla en cuestión.