Postgresql 删除运行时间过长的查询

Postgresql 删除运行时间过长的查询,postgresql,sql-delete,Postgresql,Sql Delete,我知道这可能是多余的,但我已经让同一个查询运行了将近3天,在我杀死它之前,我想得到一个社区健全性检查 DELETE FROM mytble WHERE ogc_fid NOT IN (SELECT MAX(dup.ogc_fid) FROM mytble As dup GROUP BY dup.id) mytble是表的名称,ogc_fid是唯一id字段的名称,id是我想要作为唯一id的字段的名称。表中有4100万条

我知道这可能是多余的,但我已经让同一个查询运行了将近3天,在我杀死它之前,我想得到一个社区健全性检查

DELETE
FROM    mytble
WHERE   ogc_fid NOT IN
    (SELECT     MAX(dup.ogc_fid)
        FROM        mytble As dup
        GROUP BY    dup.id)

mytble是表的名称,ogc_fid是唯一id字段的名称,id是我想要作为唯一id的字段的名称。表中有4100万条记录,索引都已生成,所以我仍然有点担心为什么要花这么长时间才能完成。对此有何想法?

如果您提供解释输出,那就太好了,但如果您再次这样做,您所做的可能会更快,我会查找解释:


如果我理解正确,您希望删除所有记录,其中包含具有相同dup_id的记录 但如果ogc_较高,则存在fid。只保留那些ogc_fid最高的

-- DELETE -- uncomment this line and comment the next line if proven innocent.
SELECT COUNT(*)
  FROM   mytble mt
 WHERE   EXISTS (
  SELECT *
    FROM mytble nx
   WHERE nx.dup_id = mt.dup_id    -- there exists a row with the same dup_id
     AND nx.ogc_fid > mt.ogc_fid  -- , ... but with a higher ogc_fid 
);
在dup_id和ogc_id上有一个索引,对于4100万条记录,这应该运行几分钟

更新:如果不存在索引,您可以通过首先创建索引来加速上述查询:

 CREATE UNIQUE INDEX sinterklaas ON mytble (dup_id, ogc_id);

向您的问题添加查询计划。只需将唯一记录选择到新表中,然后删除旧记录,可能会更简单吗?基本上,我有一个包含大量重复记录的表,我想删除它们。重复项在id字段中标识,唯一id列称为ogc_fid。因此,我想根据id字段删除重复项。这更有意义吗?你的意思是:如果存在某个实体的副本,它们将具有相同的dup_id,但不同的ogc_fid。我将添加一个索引定义。另外,通过SELECT COUNT*FROM-trick替换DELETE FROM可以检查受影响的行和查询的估计运行时间!谢谢你们两位的代码片段!
 CREATE UNIQUE INDEX sinterklaas ON mytble (dup_id, ogc_id);