Oracle: определение дубликатов в таблице без индекса - PullRequest
6 голосов
/ 22 марта 2010

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

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

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

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

Спасибо!

Ответы [ 5 ]

7 голосов
/ 22 марта 2010

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

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

2 голосов
/ 23 марта 2010

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

Если у вас еще нет таблицы EXCEPTIONS, создайте ее с помощью предоставленного сценария:

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

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

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

Это не удастся, но теперь ваша таблица ИСКЛЮЧЕНИЙ содержит список всех строк, ключи которых содержат дубликаты, идентифицируемые ROWID. Это дает вам основание для решения, что делать с дубликатами (удалить, перенумеровать, что угодно).

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

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

1 голос
/ 22 марта 2010

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

1 голос
/ 22 марта 2010

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

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

0 голосов
/ 22 марта 2010

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

...