2010-03-22 12 views
6

Cuando intento crear un índice único en una tabla grande, obtengo un error de restricción único. El índice único en este caso es una clave compuesta de 4 columnas.Oracle: Identificación de duplicados en una tabla sin índice

¿Hay una manera eficiente para identificar los duplicados que no sean:

select col1, col2, col3, col4, count(*) 
from Table1 
group by col1, col2, col3, col4 
having count(*) > 1 

La explicar el plan anterior muestra la tabla con análisis completo del costo extremadamente alto, y sólo quiero encontrar si hay otra manera.

Gracias!

+0

http://www.remote-dba.cc/oracle_tips_duplicate_rows.htm –

Respuesta

7

Primero intente crear un índice no exclusivo en estas cuatro columnas. Eso tomará el tiempo O (n log n), pero también reducirá el tiempo necesario para realizar el select a O (n log n).

Estás en un aprieto aquí: de cualquier forma que lo cortes, toda la tabla debe leerse al menos una vez. El algoritmo na ï ve se ejecuta en O (n) tiempo, a menos que el optimizador de consultas sea lo suficientemente astuto como para crear un índice/tabla temporal.

+3

Después de haber resuelto su problema no exclusivo, puede aplicar la restricción única utilizando el índice no único que ha creado.No le permitirá crear un índice único mientras tenga un índice no único en las mismas columnas, de modo que si REALMENTE desea un índice único, cree su índice no único como crear el índice t_ix en la tabla 1 (col1, col2, col3) , col4,1); Con el literal al final, no lo detendrá más tarde creando el índice único en col1, col2, col3, col4 y luego soltando el índice no único –

+0

Todas las respuestas indicaron que no hay una forma fácil de resolver este problema. Pero esta respuesta también me dio un enfoque, así que elegí esta como la mejor respuesta a mi problema. Gracias Jeff. –

1

Dado que no hay un índice en esas columnas, esa consulta tendría que hacer un escaneo completo de la tabla, no hay otra manera de hacerlo realmente, a menos que una o más de esas columnas ya esté indexada.

Puede crear el índice como un índice no único, luego ejecutar la consulta para identificar las filas duplicadas (que debe ser muy rápido una vez que se crea el índice). Pero dudo si el tiempo combinado de creación del índice no único y la ejecución de la consulta fuera menor que solo ejecutar la consulta sin el índice.

0

Desafortunadamente, no creo que haya una manera más rápida.

1

De hecho, debe buscar un duplicado de cada fila en una tabla. No hay manera de hacer esto de manera efectiva sin un índice.

2

Puede usar la cláusula EXCEPTIONS INTO para atrapar las filas duplicadas.

Si aún no dispone de una mesa de EXCEPCIONES crear uno con el guión previsto:

SQL> @$ORACLE_HOME/rdbms/admin/ultexcpt.sql 

Ahora se puede intentar crear una restricción única como esta

alter table Table1 
add constraint tab1_uq UNIQUE (col1, col2, col3, col4) 
exceptions into exceptions 
/

Este fallará pero ahora su tabla EXCEPTIONS contiene una lista de todas las filas cuyas claves contienen duplicados, identificados por ROWID. Eso le da una base para decidir qué hacer con los duplicados (eliminar, renumerar, lo que sea).

edición

Como otros han dicho que tiene que pagar el costo de la exploración de la mesa una vez. Este enfoque le proporciona un conjunto permanente de filas duplicadas, y ROWID es la forma más rápida de acceder a una fila determinada.

Cuestiones relacionadas