Oracle: Идентификация дубликатов в таблице без индекса

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

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

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

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

Спасибо!

6
задан FrustratedWithFormsDesigner 22 March 2010 в 20:41
поделиться

5 ответов

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

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

7
ответ дан 9 December 2019 в 22:32
поделиться

Фактически, вам нужно искать дубликат каждой отдельной строки в таблице. Без индекса это невозможно сделать эффективно.

1
ответ дан 9 December 2019 в 22:32
поделиться

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

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

1
ответ дан 9 December 2019 в 22:32
поделиться

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

0
ответ дан 9 December 2019 в 22:32
поделиться

Вы можете использовать предложение 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
/

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

править

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

2
ответ дан 9 December 2019 в 22:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: