2010-03-05 13 views
12

Tengo una tabla bastante grande con 19 000 000 de registros, y tengo un problema con las filas duplicadas. Hay muchas preguntas similares incluso aquí en SO, pero ninguna parece darme una respuesta satisfactoria. Algunos puntos a considerar:Eliminar duplicados de una tabla grande

  • Fila singularidad está determinada por dos columnas, y location_iddatetime.
  • Me gustaría mantener el tiempo de ejecución lo más rápido posible (< 1 hora).
  • Copiar tablas no es muy factible ya que la tabla tiene varios gigabytes de tamaño.
  • No hay necesidad de preocuparse por las relaciones.

Como se ha dicho, cada location_id sólo puede tener una distinta datetime, y me gustaría para eliminar todas las instancias duplicadas. No importa cuál de ellos sobreviva, ya que los datos son idénticos.

¿Alguna idea?

+3

Considere eliminar temporalmente los índices, activadores si existen. – Pentium10

+0

¿Qué estuvo mal con el enfoque dado en http://stackoverflow.com/questions/1585412/sql-to-delete-duplicate-records-in-a-table? – Mike

+0

@ Pentium10, buen punto, podría acelerar las cosas, pero también podría matar el rendimiento si sigo con la solución de subconsulta. –

Respuesta

15

Creo que se puede utilizar esta consulta para eliminar los registros duplicados de la tabla

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime) 

Antes de hacer esto , simplemente pruebe con algunos datos de muestra primero ... y luego Pruebe esto ....

Nota: En la versión 5.5, funciona en MyISAM pero no en InnoDB.

+0

Esto parece prometedor, no había escuchado sobre esta característica antes. Pruébalo ahora, te dejaré saber cómo resulta. Y bienvenido a SO :) –

+6

Esto funcionó, gracias. Tomó 31 minutos para pasar por 16 982 040 filas con 1 589 908 duplicados.No puedo creer que sea así de simple, sin tablas adicionales ni consultas complejas. :) –

+0

@Vinodkumar Saravana, estoy ejecutando 5.5 con InnoDB, leí tu nota, pero lo intenté para estar seguro. (Por supuesto que no funcionó), pero ¿puedes explicar por qué no funciona en InnoDB? – 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 

por lo que mantener la línea con la fecha y hora más baja. No estoy seguro acerca de Potencia, que depende de su columna de la tabla, su servidor, etc ...

0

Esta consulta funciona perfectamente para todos los casos: probado para Engine: MyIsam para 2 millones de filas.

ALTER TABLE nombre_tabla ADD IGNORE único (location_id, fecha y hora)

0

Puede eliminar duplicados utilizando estos pasos: 1- exportar los resultados de la consulta siguiente en un archivo txt:

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

2- Agregar esto a la primera de arriba archivo txt y ejecutar la consulta final:

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

Tenga en cuenta que '...' es el contenido del archivo txt i creados n el primer paso.

Cuestiones relacionadas