Cómo reconstruir índices de tipo LOB y segmentos LOB
Crear tabla test
(id int,
Clob de texto
);
SQL gtselect * del usuario _ segmentos
Nombre del segmento nombre de partición tipo de segmento nombre del espacio de tabla
bloque de bytes área de extensión INICIAL _ EXTENSIÓN SIGUIENTE _ EXTENSIÓN MIN _ EXTENSIÓN MÁX _ EXTENSIÓN PCT _ AUMENTAR FREELIST FREELIST _ GRUPOS BUFFER _ POOL
- - - -
- - - - - - - - - - - - -
Usuario de tabla de prueba
41943040 5120 55 65536 1 2147483645 predeterminado
SYS _ il 0000049476 c 00002 $ $ usuario de índice lob
65536 8 1 65536 1 2147483645Predeterminado
SYS _ lob 0000049476 c 00002 $ $ lob segmento usuario
65536 8 1 65536 1 2147483645Predeterminado
alterar índice SYS _ il 0000049476 c 00002 $$Reconstruir usuario de espacio de tabla en línea sin registro
ORA-02327: No se puede crear un índice usando la expresión del tipo de datos LOB.
Recordemos primero el conocimiento relevante. Lo siguiente es de Oracle 9i; El arte de la programación 10G
Lobindex y lobsegment, ¿qué hacen? Estos segmentos se crearon para respaldar nuestra columna LOB. Nuestros datos LOB reales se almacenan en un segmento LOB (en realidad, los datos LOB también se pueden almacenar en la tabla T, pero lo analizaremos más adelante.
Esto será más detallado cuando el almacenamiento en la cláusula de fila esté habilitado explicación). LOBindex se utiliza para realizar la navegación de un globo para encontrar algunas partes del mismo. Al crear una columna LOB, en términos generales, se trata de un puntero (
puntero) o localizador LOB. Lo que obtiene nuestra aplicación es este localizador LOB. Al solicitar "12.000 ~ 2000 bytes" de un LOB, el localizador de LOB se utilizará para indexar lobin para encontrar estos bytes.
Guarda su ubicación y luego accede al segmento lobsegmento. Las partes de un LOB se pueden encontrar fácilmente usando lobindex. Desde esta perspectiva, se puede considerar una LOB como una relación maestro/esclavo.
El globo en la tabla en realidad solo apunta al índice de lob, y el índice de lob apunta a varias partes del propio lob. Para obtener N~M bytes en un LOB, se debe eliminar la referencia al puntero en la tabla (localizador de LOB) y se debe recorrer la estructura lobindex para encontrar lo que se necesita.
Base de datos (fragmento) y luego se accede en secuencia. Esto hace que el acceso aleatorio a cualquier parte del LOB sea igualmente rápido; puede obtener la primera, la mitad o la última parte del LOB a la misma velocidad porque no es necesario atravesar el LOB desde el principio.
ORACLE también dijo: el índice lob es una estructura interna estrechamente relacionada con el almacenamiento lob. Esto significa que no se permite la reconstrucción directa.
Pero creo que está claro que INDEX se utiliza para determinar la ubicación de LOBSEGMENT.
Si a menudo realiza DML en filas de la tabla o DML en campos grandes, creo que aún es necesaria la refactorización.
Al ser un índice se debe seguir el principio de indexación. Una gran cantidad de DML inevitablemente hará que los nodos de la página de índice sean cada vez más profundos, pero contiene espacio libre.
ORACLE METALINK recomienda utilizar el comando ALTER TABLE... move para reconstruir el índice, es decir, utilizar la instrucción ALTER TABLE MOVE para reconstruir el índice.
Probémoslo:
Para comprender los resultados experimentales, primero debemos comprender varios conceptos:
1. La cláusula predeterminada en ROW es (Habilitar almacenamiento). en la fila), es decir, si es menor a 4000 bytes, se almacenará en el segmento de tabla, y si es mayor a 4000 bytes, se almacenará en el segmento lob. Al mismo tiempo, se utiliza LOBINDEX para especificar la ubicación.
Usa DESACTIVAR ALMACENAMIENTO EN FILA, es decir, por muy grande que sea, existe en LOBSEGMENTO.
2.CHUNK representa la unidad de almacenamiento del LOGSEGMENT más pequeño, y un CHUNK solo se usa para una línea de segmento. Si un CHUNK está configurado en 32K y su línea de segmento es solo de 2K, entonces se desperdician 30k.
3. El caché indica si se registran lecturas en segmentos de registro en el caché. El valor predeterminado es NOCACHE, que se puede almacenar en caché y lecturas en caché. El primero guarda tanto la lectura como la escritura, mientras que el segundo guarda la lectura y escribe directamente. Y NOCACHE significa lectura y escritura directa.
La siguiente es la declaración que utilicé para crear la tabla.
Crear tabla "PPTEST". "Prueba 2 "
("ID" número (*, 0),
" TXT" CLOB
)pct gratis 10 PCTUSED 40 init trans 1 MAXTRANS 255 sin registro de compresión
Almacenamiento (inicial 65536 siguiente 1048576 extensión máxima 1 extensión máxima 2147483645
PCTINCREASE 0 lista libre 1 grupo de lista libre 1 BUFFER_POOL predeterminado)
Tabla espacio "Usuario"
LOB ("TXT") almacenado como (
Espacio de tabla "Usuario" bloque de fila deshabilitado almacenado en 8192 por ciento versión 10
Nokach
Almacenamiento (inicial 65536 siguiente 1048576 extensión máxima 1 extensión máxima 2147483645
PCTINCREASE 0 lista libre 1 grupo de lista libre 1 valor predeterminado BUFFER_POOL))
Desactivé el almacenamiento en bloque de fila 8192, que es 8K.
Ahora inserto los datos.
SQL gt insert test 2
2 seleccione * de la prueba
Inserte 589824 filas
Aquí hay 58W de líneas múltiples. Calcula el espacio que ocupa el segmento de recta.
589824*8K=4.5G
Mira esto:
selecciona NOMBRE_SEGMENTO, TIPO_SEGMENTO, BYTES/1024/1024/1024 GB, BLOQUES del usuario _ segmentos
SYS _ il 0000049480 c 00002 $ $ lob índice 0.0302733968
SYS _ lob 0000049480 c 00002 $ $ lob segmento 4.54199218 595328
Tabla de prueba 2 0.01855468 2432
>Hechos Arriba, nuestro LOGSEGMENT es 4.5GAhora recopilamos información estadística y analizamos el índice de la siguiente manera:
SQL gt ejecuta DBMS_stats.gather_schema_stats(own name = gt; 'PPTEST', cascade = gt true);
Procedimiento PL/SQL completado exitosamente
Analizando índice SYS_il 0000049480 c 00002 $$ validar estructura;
Análisis índice SYS_il 0000049480 c 00002 $ $ calcular estadísticas;
No sé por qué no pude encontrar la información de la estructura de LOGINDEX después de verificar.
Pero considerando que una gran cantidad de DML es suficiente, la escala de reconstrucción del índice definitivamente se reducirá.
Ahora hagamos el experimento de replegamiento.
Primero, simule la inserción de una gran cantidad de eliminaciones,
Eliminar prueba2
Insertar prueba 2
seleccione id, txt de (seleccione rownum rn, id, txt de la prueba) donde mod(rn, 8) = 0
Elimine todo primero y luego inserte 1/8 de los datos. (El proceso es extremadamente lento)
SQL gt delete test2
Se eliminaron 589824 filas
Examen
seleccione SEGMENT_NAME, SEGMENT_TYPE, BYTES/ 1024/1024/1024 GB, bloques del usuario _ segmentos
sys _ IL 0000049480 C 00002 $ $ lob índice 0.078125 10240
sys _ lob 0000049480 c 00000000 $ lob segmento 4.6049218 6035202020202020
Tabla de prueba 2 0.01855468 2432
El número de bloques de índice ha aumentado considerablemente y el espacio ocupado también ha aumentado considerablemente. No entiendo muy bien por qué se agregan tantos aquí. En realidad no hay datos en este momento.
Luego se insertó.
SQL gt insert test 2
2 seleccione id, txt de (seleccione rownum rn, id, txt de prueba) donde mod (rn, 8) = 0
;Insertar fila 73728
EXAMEN
seleccione NOMBRE_SEGMENTO, TIPO_SEGMENTO, BYTES/1024/1024/1024 GB, BLOQUES del usuario _ segmentos
SYS_il 0000049480 c 00002 $ $ índice lob 0.0859375 11264
SYS _ lob 0000049480 c 00002 $ $ segmento lob 5.65449218 669056
Tabla de prueba 2 0.01855468 2432
De hecho en este momento Los datos son solo 1/8, pero LOGSEGMENT y LOBINDEX son más grandes. Entonces se desperdicia mucho espacio.
Reconstruimos directamente la tabla TEST2.
SQL gtalter table test2 usuario del espacio de tabla móvil;
Examen
SYS _ il 0000049480 c 00002 $ $ lob index 0.0859375 11264
SYS_lob 0000049480 c 00002 $$ segmento lob 5.65449218 669056
Tabla de prueba 2 0.00292968 384
Acabo de reconstruir la parte de prueba 2.
Usar declaración
Cambiar tabla test2 mover
Usuario de espacio de tabla
LOB (TXT) almacenado como segmento lobs
(Usuario del espacio de tabla);
Realizar reconstrucción
Los objetos temporales que se pueden ver durante la reconstrucción son los siguientes:
4.635 Temporal 0.00061035 80
4.187 Temporal 0.1328125 17408
4.611 Temporal 0.00097656 128
Obviamente, la tabla en sí, LOBSEGMENT y LOBINDEX están todos reconstruidos.
Luego verifique
SQL gtselect SEGMENT_NAME, SEGMENT_TYPE, BYTES/1024/1024/1024 GB, BLOCKS del usuario _ segmentos
Nombre del segmento tipo de segmento GB Bloque de datos
- - - -
Tabla de prueba 2 0.00292968 384
LOBSEGMENT
SYS _ il 0000049480 c 00002 $ $ índice lob 0.00390625 512
Debido a que estoy usando LOBSEGMENT aquí, el SYS_LOB0000049480C00002$$ $ anterior se ha cambiado a lobsegment. Se puede ver que la capacidad es normal en este momento. 0,56G es sólo 1/8 del anterior.
Si desea reconstruirlo por separado, se informará un error.
El registro en METALINK es el siguiente:
Descripción
-
' ALTER TABLE foo MODIFY LOB (lobcol)... sintaxis no permitida
Cambios en el espacio de tabla
Cambiar tabla my_lob
Modificar LOB (a_lob)
(espacio de tabla new _ tbsp);
(tablespace new_tbsp)
*
ORA-22853: especificación de opción de almacenamiento LOB no válida
Debe utilizar la palabra clave MOVE como se muestra en el ejemplo.
Conclusión:
1 y LOGSEGMENT no reutilizarán el espacio debajo del HWM, por lo que una gran cantidad de DML aumentará continuamente su tamaño.
2. Es necesario reconstruir LOBsegment y LOBINDEX. La sintaxis es la siguiente:
Cambiar tabla test2 mover
Usuario del espacio de tabla
LOB (TXT) se almacena como segmento lobs
( usuario del espacio de tabla);
Debe reconstruirse junto con la tabla, no hay forma de reconstruir LOBSEGMENT o LOGINDEX por separado.