2010-03-05 20 views
12

Ich habe eine recht große Tabelle mit 19 000 000 Datensätzen, und ich habe Probleme mit doppelten Zeilen. Es gibt viele ähnliche Fragen auch hier in SO, aber keine von ihnen scheint mir eine befriedigende Antwort zu geben. Einige Punkte zu beachten:Löschen von Duplikaten aus einer großen Tabelle

  • Row Einzigartigkeit von zwei Säulen bestimmt wird, location_id und datetime.
  • Ich möchte die Ausführungszeit so schnell wie möglich halten (< 1 Stunde).
  • Kopieren von Tabellen ist nicht sehr machbar, da die Tabelle mehrere Gigabyte groß ist.
  • Keine Notwendigkeit, sich um Beziehungen zu sorgen.

Wie gesagt, jeder location_id nur ein bestimmtes datetime haben kann, und ich möchte alle doppelten Instanzen entfernen. Es spielt keine Rolle, welcher von ihnen überlebt, da die Daten identisch sind.

Irgendwelche Ideen?

+3

Berücksichtigen Sie, um Indizes vorübergehend zu entfernen, wenn Trigger vorhanden sind. – Pentium10

+0

Was war falsch mit dem Ansatz in http://stackoverflow.com/questions/1585412/sql-to-delete-duplicate-records-in-a-table? – Mike

+0

@ Pentium10, guter Punkt, könnte die Dinge beschleunigen, aber könnte auch Leistung zu töten, wenn ich mit der Unterabfrage Lösung durchgehen. –

Antwort

15

Ich denke, Sie diese Abfrage verwenden können, die doppelte Datensätze aus der Tabelle löschen

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime) 

Bevor Sie dies tun , nur mit ein paar Beispieldaten zuerst testen ... und dann versuchen Sie es ....

Hinweis: Auf Version 5.5 funktioniert es auf MyISAM aber nicht InnoDB.

+0

Das sieht vielversprechend aus, ich hatte noch nie von dieser Funktion gehört. Versuch es jetzt, ich werde dich wissen lassen, wie es sich herausstellt. Und willkommen bei SO :) –

+6

Das hat funktioniert, danke. Es dauerte 31 Minuten, um 16 982 040 Zeilen mit 1 589 908 Duplikaten zu durchlaufen.Ich kann nicht glauben, dass es so einfach sein könnte, ohne zusätzliche Tabellen oder komplexe Abfragen. :) –

+0

@Vinodkumar Saravana, Ich laufe 5,5 mit InnoDB, ich lese Ihre Notiz, aber ich habe es trotzdem versucht, nur um sicher zu sein. (Natürlich hat es nicht funktioniert), aber kannst du bitte erklären, warum es bei InnoDB nicht funktioniert? – tixastronauta

1
SELECT *, COUNT(*) AS Count 
FROM table 
GROUP BY location_id, datetime 
HAVING Count > 2 
0
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 

So halten Sie die Zeile mit dem unteren Datetime. Ich bin mir nicht sicher perf, hängt es von Ihrer Tabellenspalte, Ihren Server etc ...

0

Diese Abfrage funktioniert perfekt für jeden Fall: getestet für Engine: MyIsam für 2 Millionen Zeilen.

ALTER TABLE table_name IGNORE ADD UNIQUE (location_id, Datetime)

0

Sie Duplikate löschen können mit diesen Schritten: 1- Export die Ergebnisse der folgenden Abfrage in eine txt-Datei:

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

2- hinzufügen dies auf den ersten von oben txt-Datei und starten Sie die letzte Abfrage:

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

Bitte beachten Sie, dass ‚...‘ ist der Inhalt der txt-Datei i erstellt n der erste Schritt.

Verwandte Themen