Red de conocimiento informático - Conocimiento informático - Cómo reconstruir índices de tipo LOB y segmentos LOB

Cómo reconstruir índices de tipo LOB y segmentos LOB

Cuando queremos reconstruir un índice de tipo LOB, ocurrirá un error, el cual se reproduce de la siguiente manera:

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.5G

Ahora 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.