2013-11-02 6 views
3

Необходимо удалить повторяющиеся записи из таблицы. Таблица содержит только 33 столбца только PK_NUM - это первичные ключевые столбцы. Поскольку PK_NUM содержит уникальные записи, нам нужно рассмотреть либо значение min/max.Удалить дубликаты записей в таблице oracle: размер 389 ГБ

  1. Всего записей в таблице: 1766799022
  2. Отдельные записи в таблице: 69237983
  3. повторяющихся записей в таблице: 1697561039

детали Колонка:

  • 4: Дата данных типа
  • 4: Номер типа данных
  • 1: Данные Char Тип
  • 24: тип данных VARCHAR2

Размер стола: 386 GB

DB детали: Oracle Database 11g EE :: 11.2.0.2.0 :: 64bit Производство

образец данных:

  • col1, col2, col3
  • 1, АВС, 123
  • 2, PQR, 456
  • 3, ABC, 123

Ожидаемые данные должны содержит только две записи:

  • col1, col2, col3
  • 1 АВС, 123
  • 2, PQR, 456

* 1 можно заменить d на 3, наоборот.

Мой план здесь является

  1. Вытяните различные записи и хранить его в спину таблице. (Т.е. с помощью вставки в выберите)
  2. усечь существующую таблицу и переместить записи из обратно к существующим.

Как размер данных огромен,

  1. Хочет знать, что является оптимизированной SQL для извлечения различных записей
  2. Любой оценки того, сколько потребуется для завершения (вставить в выберите) и обрезать существующую таблицу.

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

+1

Из моего опыта вставка будет намного быстрее, чем удаление. Таким образом, ваш подход звучит хорошо. Вы можете сделать это еще быстрее, когда вы отбрасываете исходную таблицу и резервную копию на старое имя и воссоздаете все ограничения. Затем вы сохраняете работу по повторной вставке строк. –

+0

Сколько столбцов вам нужно сравнивать для отличимости? –

+0

Для сравнения отличия необходимо использовать 15 столбцов –

ответ

1

попробовать это:

rename table_name to table_name_dup; 

, а затем:

create table table_name 
as 
select 
    min(col1) 
, col2 
, col3 
from table_name_dup 
group by 
    col2 
, col3; 

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

drop table table_name_dup; 
+0

[Сортировка и хеширование выполняются во временном табличном пространстве] (http://docs.oracle. ком/кд/E11882_01/server.112/e40540/physical.htm # CNCPT1112). Для этой операции потребуется около 389 ГБ временного табличного пространства. –

+0

389 ГБ временное табличное пространство недоступно в соответствии с моим администратором базы данных ... любое другое обходное решение –

+0

См. Предложение хэш-разбиения в моем ответе. Если у вас есть доступ к разделу, это значительно сократит ваши временные требования к сортировке. –

2

Один из вариантов для создания этой памяти эффективна для вставки (NOLOGGING Append) все строки в таблице, хэш распределяли в списке столбцов на котором должны быть обнаружены дубликаты, или если есть ограничение на количество столбцов, то на столько, сколько вы можете использовать (с целью использования с максимальной избирательностью). Используйте что-то вроде 1024 разделов, и каждый в идеале будет около

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

Таким образом, для каждого раздела вы можете сделать что-то вроде ...

insert /*+ append */ into new_table 
select * 
from temp_table partition (p1) t1 
where not exists (
     select null 
     from temp_table partition (p1) t2 
     where t1.col1 = t2.col1 and 
       t1.col2 = t2.col2 and 
       t1.col3 = t2.col3 and 
       ... etc ... 
       t1.rownum < t2.rownum); 

Ключом к хорошей производительности здесь является то, что хэш-таблица, созданная для выполнения анти-присоединиться к этому запросу, который будет почти такой же большой, как и сам раздел, сможет вписаться в память. Поэтому, если вы можете управлять зоной сортировки 2 ГБ, вам нужно как минимум 389/2 = около 200 табличных разделов. Радиус действия до ближайшей мощности двух, поэтому в этом случае сделайте 256 разделов таблицы.

Смежные вопросы