Mysql 保留表中重复项的最早实例

Mysql 保留表中重复项的最早实例,mysql,sql,mariadb,Mysql,Sql,Mariadb,我们遇到了这样一种情况:重复的条目已经悄悄地进入了我们的表,其中包含超过6000万个条目(这里的重复意味着所有字段,除了AUTO_INCREMENT index字段外,都具有相同的值)。我们怀疑表中大约有200万个重复条目。我们希望删除这些重复条目,以便保留重复条目的最早实例 让我用一个说明性的表格来解释: CREATE TABLE people ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(40) NOT NULL DEFAUL

我们遇到了这样一种情况:重复的条目已经悄悄地进入了我们的表,其中包含超过6000万个条目(这里的重复意味着所有字段,除了AUTO_INCREMENT index字段外,都具有相同的值)。我们怀疑表中大约有200万个重复条目。我们希望删除这些重复条目,以便保留重复条目的最早实例

让我用一个说明性的表格来解释:

CREATE TABLE people
(
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(40) NOT NULL DEFAULT '',
age INT NOT NULL DEFAULT 0,
phrase VARCHAR(40) NOT NULL DEFAULT '',
PRIMARY KEY (id)
);

INSERT INTO people(name, age, phrase) VALUES ('John Doe', 25, 'qwert'), ('William Smith', 19, 'yuiop'),
('Peter Jones', 19, 'yuiop'), ('Ronnie Arbuckle', 32, 'asdfg'), ('Ronnie Arbuckle', 32, 'asdfg'),
('Mary Evans', 18, 'hjklp'), ('Mary Evans', 18, 'hjklpd'), ('John Doe', 25, 'qwert');

SELECT * FROM people;
+----+-----------------+-----+--------+
| id | name            | age | phrase |
+----+-----------------+-----+--------+
|  1 | John Doe        |  25 | qwert  |
|  2 | William Smith   |  19 | yuiop  |
|  3 | Peter Jones     |  19 | yuiop  |
|  4 | Ronnie Arbuckle |  32 | asdfg  |
|  5 | Ronnie Arbuckle |  32 | asdfg  |
|  6 | Mary Evans      |  18 | hjklp  |
|  7 | Mary Evans      |  18 | hjklpd |
|  8 | John Doe        |  25 | qwert  |
+----+-----------------+-----+--------+
我们希望删除重复条目,以便获得以下输出:

SELECT * FROM people;
+----+-----------------+-----+--------+
| id | name            | age | phrase |
+----+-----------------+-----+--------+
|  1 | John Doe        |  25 | qwert  |
|  2 | William Smith   |  19 | yuiop  |
|  3 | Peter Jones     |  19 | yuiop  |
|  4 | Ronnie Arbuckle |  32 | asdfg  |
|  6 | Mary Evans      |  18 | hjklp  |
|  7 | Mary Evans      |  18 | hjklpd |
+----+-----------------+-----+--------+
对于较小尺寸的表,以下方法可行:

CREATE TABLE people_uniq LIKE people;

INSERT INTO people_uniq SELECT * FROM people GROUP BY name, age, phrase;

DROP TABLE people;

RENAME TABLE people_uniq TO people;

SELECT * FROM people;
+----+-----------------+-----+--------+
| id | name            | age | phrase |
+----+-----------------+-----+--------+
|  1 | John Doe        |  25 | qwert  |
|  2 | William Smith   |  19 | yuiop  |
|  3 | Peter Jones     |  19 | yuiop  |
|  4 | Ronnie Arbuckle |  32 | asdfg  |
|  6 | Mary Evans      |  18 | hjklp  |
|  7 | Mary Evans      |  18 | hjklpd |
+----+-----------------+-----+--------+


请建议一个解决方案,它可以扩展到一个包含数千万个条目和更多列的表。我们使用的是MySQL版本
5.6.49

为什么不删除重复项

DELETE FROM people
where id in (
SELECT MAX(id) 
FROM people 
GROUP BY name, age, phrase
HAVING count(*) > 1
)

如果仍然需要花费太多的时间,您可以批量执行

如果您首先在
姓名、年龄、短语
上创建索引,这不会加快
按姓名、年龄、短语从人员组中选择*的速度吗?此外,您还写道“我们希望删除这些重复项,以便保留重复项的最早实例”,但较小表的示例不一定保留重复项的最早实例。这真的是一个必要的约束吗?是的,我的错。这个表除了主索引之外没有其他索引。您的查询将在OP的表上无限长地执行。索引在这里没有帮助,因为他需要按所有列进行分组,实际上在删除操作中没有索引帮助。