2010-03-22 5 views
6

Когда я пытаюсь создать уникальный индекс в большой таблице, я получаю уникальную ошибку. Уникальным индексом в этом случае является составной ключ из 4 столбцов.Oracle: идентификация дубликатов в таблице без индекса

Есть ли эффективный способ определить, кроме дубликатов:

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

объяснить план выше показывает полный просмотр таблицы с чрезвычайно высокой стоимостью, и просто хочет найти, если есть другой способ.

Спасибо!

+0

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

ответ

7

Попробуйте создать уникальный код на этих четырех столбцах. Это займет время O (n log n), но также уменьшит время, необходимое для выполнения select в O (n log n).

Вы находитесь в некоторой привязке здесь - любым способом вы его обрезаете, вся таблица должна быть прочитана хотя бы один раз. Алгоритм v ï ведется в O (n) времени, если оптимизатор запросов не является достаточно умным для создания временного индекса/таблицы.

+3

После того, как вы устранили неповторимую проблему, вы можете принудительно применить уникальное ограничение, используя созданный вами уникальный код.Это не позволит вам создать уникальный индекс, в то время как у вас есть уникальный код в тех же столбцах, поэтому, если вы действительно хотите уникальный индекс, создайте свой неидеальный индекс в качестве индекса создания t_ix в таблице1 (col1, col2, col3 , col4,1); С литеральным в конце, это не остановит вас позже, создав уникальный индекс на col1, col2, col3, col4, а затем опустив уникальный код –

+0

. Все ответы показали, что из этой проблемы нет простого выхода. Но этот ответ также дал мне подход, поэтому я выбрал это как лучший ответ на мою проблему. Спасибо Джеффу. –

1

Поскольку в этих столбцах нет индекса, этот запрос должен будет выполнять полное сканирование таблицы - нет другого способа сделать это, если только один или несколько из этих столбцов уже не проиндексированы.

Вы можете создать индекс как не уникальный индекс, а затем запустить запрос для идентификации повторяющихся строк (который должен быть очень быстрым после создания индекса). Но я сомневаюсь, что совместное время создания неидеального индекса, после которого выполняется запрос, будет меньше, чем просто запуск запроса без индекса.

0

Я не думаю, что к сожалению, есть более быстрый путь.

1

На самом деле вам нужно найти дубликат каждой строки в таблице. Нет способа сделать это эффективно без индекса.

2

Вы можете использовать предложение EXCEPTIONS INTO, чтобы уловить дублированные строки.

Если вы не уже есть таблица ИСКЛЮЧЕНИЯ создать с помощью прилагаемого сценария:

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

Теперь вы можете попытаться создать уникальное ограничение, как этот

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

Это подведет, но теперь ваша таблица EXCEPTIONS содержит список всех строк, ключи которых содержат дубликаты, идентифицированные ROWID. Это дает вам основание для решения, что делать с дубликатами (удалить, перенумеровать, что угодно).

редактировать

Как уже отмечалось, вы должны оплатить стоимость сканирования таблицы один раз. Этот подход дает вам постоянный набор дублированных строк, а ROWID - это самый быстрый способ доступа к любой заданной строке.