Удаление дубликатов с большого стола - PullRequest
12 голосов
/ 05 марта 2010

У меня довольно большая таблица с 19 000 000 записей, и у меня проблема с дублирующимися строками.Есть много подобных вопросов даже здесь, в SO, но ни один из них, кажется, не дает мне удовлетворительного ответа.Некоторые моменты, которые следует учитывать:

  • Уникальность строки определяется двумя столбцами: location_id и datetime.
  • Я бы хотел, чтобы время выполнения было максимально быстрым (<1 час). </li>
  • Копирование таблиц не очень выполнимо, поскольку размер таблицы составляет несколько гигабайт.
  • Не нужно беспокоиться об отношениях.

Как сказанокаждый location_id может иметь только один отдельный datetime, и я хотел бы удалить все повторяющиеся экземпляры.Неважно, кто из них выживет, поскольку данные идентичны.

Есть идеи?

Ответы [ 5 ]

16 голосов
/ 05 марта 2010

Я думаю, что вы можете использовать этот запрос, чтобы удалить дубликаты записей из таблицы

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime)

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

Примечание. В версии 5.5 он работает на MyISAM, но не на InnoDB.

1 голос
/ 05 марта 2010
SELECT *, COUNT(*) AS Count
FROM table
GROUP BY location_id, datetime
HAVING Count > 2
0 голосов
/ 12 июля 2017

Вы можете удалить дубликаты, выполнив следующие действия: 1- Экспортируйте результаты следующего запроса в текстовый файл:

select dup_col from table1 group by dup_col having count(dup_col) > 1

2- Добавьте это в первый из приведенных выше текстовых файлов и выполните последний запрос:

delete from table1 where dup_col in (.....)

Обратите внимание, что «...» - это содержимое txt-файла, созданного на первом этапе.

0 голосов
/ 07 января 2014

Этот запрос отлично работает для каждого случая: проверено на Engine: MyIsam для 2 миллионов строк.

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime)

0 голосов
/ 05 марта 2010
UPDATE table SET datetime  = null 
WHERE location_id IN (
SELECT location_id 
FROM table as tableBis
WHERE tableBis.location_id = table.location_id
AND table.datetime > tableBis.datetime)

SELECT * INTO tableCopyWithNoDuplicate FROM table WHERE datetime is not null

DROp TABLE table 

RENAME tableCopyWithNoDuplicate to table

Таким образом, вы придерживаетесь строки с более низкой датой и временем. Я не уверен насчет перфорации, это зависит от столбца вашей таблицы, вашего сервера и т.д ...

...