优化 sql 查询以从大型 table 中删除重复项目
Optimisation of sql query for deleting duplicate items from large table
任何人都可以帮助我优化其中一个查询,该查询需要 20 多分钟才能 运行 针对 300 万数据。
Table结构
-----------------------------------------------------------------------------------------
|id [INT Auto Inc]| name_id (uuid) | name (varchar)| city (varchar) | name_type(varchar)|
-----------------------------------------------------------------------------------------
查询
查询的目的是为了消除重复,这里的重复是指name_id
和name
相同。
DELETE
FROM records
WHERE id NOT IN
(SELECT DISTINCT
ON (name_id, name) id
FROM records);
我会使用存在的逻辑编写你的删除:
DELETE
FROM records r1
WHERE EXISTS (SELECT 1 FROM records r2
WHERE r2.name_id = r1.name_id AND r2.name = r2.name AND
r2.id < r1.id);
此删除查询将保留具有最小 id
值的重复项。为了加快速度,您可以尝试添加以下索引:
CREATE INDEX idx ON records (name_id, name, id);
您可能已经在标识列上有一个主键,那么您可以使用它通过以下方式按 id 排除冗余行:
WITH cte AS (
SELECT MIN(id) AS id FROM records GROUP BY name_id, name)
DELETE FROM records
WHERE NOT EXISTS (SELECT id FROM cte WHERE id=records.id)
即使没有索引,这也应该工作得相对较快,可能是因为合并连接策略。
任何人都可以帮助我优化其中一个查询,该查询需要 20 多分钟才能 运行 针对 300 万数据。
Table结构
-----------------------------------------------------------------------------------------
|id [INT Auto Inc]| name_id (uuid) | name (varchar)| city (varchar) | name_type(varchar)|
-----------------------------------------------------------------------------------------
查询
查询的目的是为了消除重复,这里的重复是指name_id
和name
相同。
DELETE
FROM records
WHERE id NOT IN
(SELECT DISTINCT
ON (name_id, name) id
FROM records);
我会使用存在的逻辑编写你的删除:
DELETE
FROM records r1
WHERE EXISTS (SELECT 1 FROM records r2
WHERE r2.name_id = r1.name_id AND r2.name = r2.name AND
r2.id < r1.id);
此删除查询将保留具有最小 id
值的重复项。为了加快速度,您可以尝试添加以下索引:
CREATE INDEX idx ON records (name_id, name, id);
您可能已经在标识列上有一个主键,那么您可以使用它通过以下方式按 id 排除冗余行:
WITH cte AS (
SELECT MIN(id) AS id FROM records GROUP BY name_id, name)
DELETE FROM records
WHERE NOT EXISTS (SELECT id FROM cte WHERE id=records.id)
即使没有索引,这也应该工作得相对较快,可能是因为合并连接策略。