2010-03-22 19 views
5

Tengo una tabla vacía que anteriormente tenía una gran cantidad de filas.Eliminar de la tabla vacía tomando forver

La tabla tiene alrededor de 10 columnas e índices en muchos de ellos, así como índices en varias columnas.

DELETE FROM item WHERE 1=1 

esto toma aproximadamente 40 segundos para completar

SELECT * FROM item 

esta toma 4 segundos.

El plan de ejecución de SELECT * FROM ITEM muestra lo siguiente;

SQL> select * from midas_item; 

no rows selected 

Elapsed: 00:00:04.29 

Execution Plan 
---------------------------------------------------------- 
0  SELECT STATEMENT Optimizer=CHOOSE (Cost=19 Card=123 Bytes=73 
     80) 

1 0 TABLE ACCESS (FULL) OF 'MIDAS_ITEM' (Cost=19 Card=123 Byte 
     s=7380) 





Statistics 
---------------------------------------------------------- 
     0 recursive calls 
     0 db block gets 
    5263 consistent gets 
    5252 physical reads 
     0 redo size 
    1030 bytes sent via SQL*Net to client 
    372 bytes received via SQL*Net from client 
     1 SQL*Net roundtrips to/from client 
     0 sorts (memory) 
     0 sorts (disk) 
     0 rows processed 

¡cualquier idea de por qué les tomaría tanto tiempo y cómo solucionarla sería muy apreciada!

+0

¿Me puede decir cuántos datos (líneas) no tiene esta tabla? – bragboy

+1

¿Hay otras tablas vacías que hacen referencia a esta tabla mediante claves externas? – dpbradley

+0

La mesa tenía aproximadamente 200k filas cuando la borré por última vez. Sin embargo, ha tenido mucho más que eso en el pasado (probablemente 2mil filas de diferencia a lo largo de su vida) – Will

Respuesta

2

Seleccionar solo hace un escaneo completo de la tabla. Por otro lado, Delete (en Oracle) tendrá que almacenar las filas eliminadas completas en los segmentos de reversión para permitirle deshacer los cambios más tarde (por lo que puede ser más lento incluso que el inserto).

Puede encontrar una discusión muy larga y útil relacionada con eso en el foro Ask Tom. Dependiendo de su caso de negocio, tal vez pueda aplicar más técnicas.

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2345591157689

2

Si tiene muchos índices en la tabla, una eliminación llevará tiempo porque cada entrada en el índice también debe eliminarse. Los índices aceleran los procesos de lectura y ralentizan la escritura u otros procesos de modificación (de ahí la selección rápida).

- EDIT: Perdón, no leí las preguntas completamente. Si la tabla está vacía, no puede ser un problema de índice. o me sorprendería si fuera -

+0

bueno, el select aún tarda 4 segundos en su propia cuenta, pero sí, rápido en comparación – Will

+0

Pero dice que la tabla ya no tiene filas, por lo que el DELETE no debe modificar los índices. –

1

Si borra regularmente todas las filas de una tabla, 'truncar la tabla XXX' es típicamente mucho más rápido que un borrado masivo. Tal vez intente eso y vea cuánto más rápido puede obtenerlo.

+0

Verdadero, pero asegúrese de entender qué hace TRUNCATE (desasigna espacio, confirma la transacción). –

+0

Utilicé truncar para eliminar todas las filas – Will

3

Si su tabla anteriormente se llenó con una gran cantidad de datos, Oracle la escaneará hasta la marca de nivel más alto, incluso si no tiene datos AHORA. Puede usar la instrucción TRUNCATE para restablecer HWM.

Also on AskTom

+0

Esta fue mi primera idea también, pero no estoy seguro de que explique por qué el DELETE es mucho más lento que SELECT. –

+0

Utilicé TRUNCATE TABLE para borrar el contenido originalmente, todavía era lento después de usarlo. – Will

4

Una posibilidad es un bloqueo. Es decir, había una fila en la tabla que había sido confirmada y bloqueada por otra eliminación. Tu eliminación se sentó y esperó en la cerradura. Cuando se cometió la transacción de bloqueo, su eliminación pudo entonces finalizar.

Una segunda posibilidad es que ejecute primero la eliminación, que extrajo los bloques del disco en el caché (lo que llevó tiempo). Cuando se ejecutó la selección, los datos estaban en la memoria caché y, por lo tanto, se ejecutaron más rápido. Creo que esto es menos probable a medida que seleccionas las estadísticas indicadas "5252 lecturas físicas", por lo que no las obtuve del caché SGA. Sin embargo, es posible que haya habido un caché de disco.

Una tercera posibilidad es que hay un disparador ANTES/DESPUÉS DE ELIMINAR (no PARA CADA FILA) que hizo algo.

Una cuarta posibilidad es que el DELETE provocó una limpieza de bloque demorada. Cuando las filas fueron realmente eliminadas, si fueron escritas en el disco antes de ser confirmadas, aún tendrían la información de bloqueo/transacción. Su eliminación aparece, lee los bloques, ve la información de la transacción ahora desactualizada, la elimina y vuelve a escribir el bloque.

Una quinta posibilidad es disputa. Tal vez solo sucedieron más al mismo tiempo que la eliminación.

Muchas posibilidades. Si puedes reproducirlo, haz un seguimiento con wait events y ejecútalo a través de TKPROF.

Cuestiones relacionadas