2010-03-22 11 views
6

Quando si tenta di creare un indice univoco su una tabella di grandi dimensioni, viene visualizzato un errore di limitazione univoco. L'indice univoco in questo caso è una chiave composta di 4 colonne.Oracle: identificazione dei duplicati in una tabella senza indice

C'è un modo efficace per identificare i duplicati diversi:

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

La spiegare piano di sopra mostra tabella completa scansione con costo estremamente elevato, e vogliono solo trovare se c'è un altro modo.

Grazie!

+0

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

risposta

7

Provare a creare un indice non univoco su queste quattro colonne. Ciò richiederà O (n log n) tempo, ma ridurrà anche il tempo necessario per eseguire select su O (n log n).

Qui sei un po 'in agguato qui - in qualsiasi modo lo si affetta, l'intero tavolo deve essere letto almeno una volta. L'algoritmo na ï viene eseguito in tempo O (n), a meno che il Query Optimizer non sia abbastanza intelligente da creare un indice/tabella temporaneo.

+3

Dopo aver risolto il problema non univoco, è possibile applicare il vincolo univoco utilizzando l'indice non univoco che è stato creato.Non ti consente di creare un indice univoco mentre hai un indice non univoco sulle stesse colonne, quindi se vuoi VERAMENTE un indice univoco, crea il tuo indice non univoco come crea un indice t_ix su tabella1 (col1, col2, col3 , col4,1); Con il letterale alla fine, non ti fermerà più tardi creando l'indice univoco su col1, col2, col3, col4 e quindi rilasciando l'indice non univoco –

+0

Tutte le risposte indicano che non esiste un modo facile per uscire da questo problema. Ma anche questa risposta mi ha dato un approccio, quindi ho scelto questa come la migliore risposta al mio problema. Grazie Jeff. –

1

Poiché non esiste alcun indice su quelle colonne, quella query dovrebbe eseguire una scansione completa della tabella, nessun altro modo per farlo in realtà, a meno che una o più di queste colonne siano già indicizzate.

È possibile creare l'indice come indice non univoco, quindi eseguire la query per identificare le righe duplicate (che dovrebbe essere molto veloce una volta creato l'indice). Ma dubito che il tempo combinato di creare l'indice non univoco e quindi l'esecuzione della query sia inferiore alla semplice esecuzione della query senza l'indice.

0

Purtroppo non penso ci sia un modo più rapido.

1

Infatti, è necessario cercare un duplicato di ogni singola riga in una tabella. Nessun modo per farlo efficacemente senza un indice.

2

È possibile utilizzare la clausola EXCEPTION INTO per intercettare le righe duplicate.

Se non si dispone già di un tavolo ECCEZIONI creare uno utilizzando lo script fornito:

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

Ora è possibile tentare di creare un vincolo univoco come questo

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

questo fallirà, ma ora la tabella EXCEPTION contiene un elenco di tutte le righe le cui chiavi contengono duplicati, identificati da ROWID. Questo ti dà una base per decidere cosa fare con i duplicati (cancella, rinumera, qualunque cosa).

modificare

Come altri hanno notato si deve pagare il costo di scansione della tabella di una volta. Questo approccio fornisce un set permanente delle righe duplicate e ROWID è il modo più veloce per accedere a qualsiasi riga specificata.

Problemi correlati