У меня есть таблица DB, которая состоит из 2,5 миллиардов записей. Есть дубликаты на сумму 11 миллионов. Какой самый быстрый способ удалить эти 11 миллионов записей?Как удалить быстрее?
ответ
Сначала положить индекс столбца или столбцов, которые определяют и содержат повторяющиеся значения,
Затем assumimg таблицу имеет первичный ключ (PK),
Delete Table T Where PK <>
(Select Min(PK) From Table
Where ColA = T.ColA
... for each column in set defined above
And ColB = T.ColB)
ПРИМЕЧАНИЕ: Можно также использовать Max (PK), все, что вы делаете, это идентификация одной записи, которая не удаляется из каждого набора дубликатов.
EDIT: Чтобы исключить широкое использование журнала транзакций и раздела UNDO, вы можете сохранить значения, которые обманы в таблице temp, а затем удалить обманы f или каждая пара внутри одной транзакции ...
Предполагая, что только один столбец (назовем его COLA, число) определяет простофили ...
Create Table Dupes (ColA Number)
Insert Dupes(ColA)
Select Distinct ColA
From Table
Group By ColA
Having Count(*) > 1
recordExists Number := 0 ;
ColAValue Number;
Select Case When Exists (Select Count(*) From Dupes)
Then 1 Else 0 End Into recordExists From Dual;
While recordExists = 1
Loop
Select (Select Max(ColA) From Dupes)
Into ColAValue From Dual;
Begin Transaction
Delete Table T
Where ColA = ColAValue
And pk <> (Select Min(Pk) From Table
Where ColA = ColAValue);
Delete Dupes Where ColA = ColAValue;
Commit Transaction;
Select Case When Exists (Select Count(*) From Dupes)
Then 1 Else 0 End Into recordExists From Dual;
End Loop;
Не протестировано, так что синтаксис может массировать ... нужду
Если вы уверены, что не изменяете целостность данных (ссылочная целостность), отключите ограничения (индексы, другие ограничения), выполните удаление, а затем включите ограничения. Сначала вы должны попробовать, чтобы убедиться, что обновление индексов при включении занимает меньше времени, чем удаление с ними.
Некоторая оптимизация запросов также может помочь, но, не зная подробностей, мы обсуждаем теоретически.
Не отбрасывайте указатель в столбцах, которые вы используете, чтобы найти дубликаты, повторное полное сканирование таблицы в 2500 000 000 строк будет очень очень медленным. – Richard
Он не будет выполнять повторное сканирование таблицы, он будет делать хэш-полуфиналы, если нет индексов. – Quassnoi
DELETE
FROM mytable
WHERE rowid IN
(
SELECT rowid
FROM (
SELECT rowid, ROW_NUMBER() OVER (ORDER BY dupfield) rn
FROM mytable r
)
WHERE rn > 1
)
или, может быть, даже это:
DELETE
FROM mytable mo
WHERE EXISTS
(
SELECT NULL
FROM mytable mi
WHERE mi.dup_field = mo.dup_field
AND mi.rowid <> mo.rowid
)
Оба эти запросы будут использовать весьма эффективно HASH SEMI JOIN
, последний будет быстрее, если нет индекса на dup_field
.
Вы можете захотеть скопировать строки, но учтите, что гораздо больше REDO
и UNDO
информации будет генерироваться при копировании 2G
строк, чем при удалении 11M
.
Как работает обновление такого размера, когда размер таблицы составляет 2,5 миллиарда? –
У меня такое ощущение, что этот запрос медленный, но он может достичь того, что требуется OP. Может ли это быть переписано как соединение? –
Будет сортировка по 'dupfield' (если на нем нет индекса), что может занять много времени. Присоединение к 'rowid' будет' HASH SEMI JOIN', что является вопросом минут на '2G' против' 11M' строк. Само удаление также займет десятки минут, в основном для генерации 'REDO' и' UNDO'. – Quassnoi
Удаление одного дубликата из многих - это сложный бизнес, и с этим множеством записей у вас есть проблема.
Один из вариантов заключается в том, чтобы повернуть проблему на голову и скопировать записи, которые вы хотите сохранить в новую таблицу. Вы можете использовать синтаксис CREATE TABLE AS SELECT DISTINCT ... NOLOGGING
, который скопирует ваши дедуплицированные записи, не используя журнал транзакций, что намного быстрее. После заполнения новой таблицы удалите/переименуйте старый и переименуйте новый.
О, и помните, хлопнуть уникальный индекс для новой таблицы, так это не повторилось.
Мораль истории ... never использовать DELETE для избавления от большого количества записей, это ужасно медленно, потому что оно должно хранить все удаленные записи в журнале повтора. Либо копировать и переключаться, либо TRUNCATE.
... и вы можете применить тот же алгоритм к команде, которая произвела продукт, который позволил только 11 000 000 повторяющихся строк ;-) Keith. – corlettk
+1 за этот ответ. У меня наверняка возникнет соблазн создать новую копию таблицы и вставить ее в нее. Ключевая вещь, которую я бы добавил, - это не помещать какие-либо индексы на эту вторичную таблицу, пока вы не скопируете эти данные - вы не хотите, чтобы ненужный урон был вынужден держать индексы до нуля при вставке данных.Мне также нравится этот подход, поскольку у него есть дополнительная защитная сетка - вам не нужно избавляться от старой таблицы, пока вы не убедитесь, что у вас есть все нужные данные. – AdaTheDev
было бы интересно сравнить время, которое требуется, чтобы скопировать 2,489 миллиарда записей против удаления 11 миллионов, используя те же предикаты –
Следует ли удалять существующие строки или создавать надлежащую новую таблицу, а старые - быстрее, зависит от множества факторов. 11 миллионов строк - это много, но это всего лишь 0,5% от общего количества строк в таблице. Вполне возможно, что воссоздание & может быть намного медленнее, чем удаление, в зависимости от того, сколько индексов существует в исходной таблице, а также где строки, которые необходимо удалить, существуют на страницах данных.
Тогда возникает вопрос, является ли исходная таблица живой или нет. Если есть вставки & обновления происходят, пока эта очистка происходит, то копия & не будет работать без достаточного количества дополнительного кода для синхронизации таблицы после факта.
И, наконец, почему необходимо, чтобы эта операция была «быстрой»? Это потому, что система должна быть отключена во время процесса? Вы можете написать процедуру, которая удаляет обманки, пока система работает вживую, но не влияет на остальную часть системы с точки зрения уничтожения. Мы решили эту проблему, в прошлом первого написания запроса, который собирает первичные ключи строк, которые будут удалены во второй таблице, например, так:
INSERT
INTO RowsToDeleteTable
SELECT PKColumn
FROM SourceTable
WHERE <conditions used to find rows to remove>
CREATE UNIQUE INDEX PK_RowsToDelete ON RowsToDeleteTable (PKColumn);
Тогда мы имеем/SQL блока PL что либо петли по рядам в курсоре, как так:
BEGIN
FOR theRow IN (SELECT PKColumn FROM RowsToDeleteTable ORDER BY 1) LOOP
<delete source table for theRow.PKColumn)
<optionally wait a bit>
commit;
END LOOP;
END;
или делает что-то вроде этого:
BEGIN
FOR theRow IN (SELECT MIN(PKColumn) FROM RowsToDeleteTable) LOOP
<delete source table for theRow.PKColumn)
<optionally wait a bit>
DELETE RowsToDeleteTable
WHERE PKColumn = theRow.PKColumn;
commit;
END LOOP;
END;
зацикливание и «SELECT MAX», очевидно, менее эффективен, но имеет то преимущество, что позволяет вам т o следить за ходом операции удаления. Мы поставили немного кода ожидания в цикле, чтобы мы могли контролировать, как сильно происходит операция по извлечению.
Начальное создание RowsToDeleteTable происходит очень быстро, и у вас есть преимущество, позволяющее процессу принимать столько, сколько захотите. В таком случае «дыры», оставшиеся в экстентах с помощью удалений, будут не слишком плохими, так как вы удаляете такой небольшой процент от общего количества данных.
- 1. Как быстрее удалить события календаря?
- 2. Удалить подвид Быстрее
- 3. удалить дублирует быстрее vb6
- 4. Как удалить пропущенные записи быстрее в Guava
- 5. Быстрее УДАЛИТЬ ж/JOIN запрос
- 6. Как удалить полное дерево каталогов как можно быстрее? Python
- 7. Почему важно удалить файлы, чтобы их быстрее удалить?
- 8. Быстрее XML Джексон: Удалить двойные кавычки
- 9. Удалить удаленные строки из таблицы быстрее.
- 10. Как удалить все сообщения из почтового ящика быстрее в Android?
- 11. Eclipse: Как я могу удалить «Установленное программное обеспечение» быстрее?
- 12. Как JVM быстрее выполняет математические вычисления быстрее?
- 13. Как сделать ВЫБРАТЬ быстрее
- 14. Как сделать отражение быстрее?
- 15. Как читать данные быстрее?
- 16. Achartengine как скользить быстрее
- 17. Как скачать быстрее?
- 18. Как перечислить каталоги быстрее?
- 19. Как сделать MATLAB быстрее?
- 20. Как сделать код быстрее?
- 21. Как сделать Алею быстрее?
- 22. Как загрузить MKMapView быстрее?
- 23. Как сделать GDB быстрее
- 24. Как сделать сайт быстрее?
- 25. Как загрузить JQuery быстрее?
- 26. Как скомпилировать ускорение быстрее?
- 27. Как вставить записи быстрее
- 28. Как сделать запрос быстрее?
- 29. Как сделать Tesseract быстрее
- 30. как отменить задачу быстрее
Чтобы получить представление о производительности системы, запрос на получение подсчета повторяющихся строк занял 1 час и 40 минут. – 2009-07-17 13:24:23
Я думаю, что OP удалил свою учетную запись. – Shimmy
Спасибо, ребята! Мне пришлось копировать уникальные записи в таблицу, обрезать исходную таблицу и копировать уникальные данные. – Chattz