Postgresql Postgres是在没有主键的大表中删除重复项的最佳方法

Postgresql Postgres是在没有主键的大表中删除重复项的最佳方法,postgresql,duplicates,Postgresql,Duplicates,我有一个记录扫描事件的表,其中存储了第一个和最后一个事件。每晚午夜,将前一天的所有扫描事件添加到表中,删除重复项,并运行查询以删除除具有最小和最大时间戳的扫描事件之外的任何内容 问题之一是数据提供程序每45天循环一次扫描ID,因此此表没有主键。以下是表格在其最终状态下的外观示例: |scaneventID|scandatetime |status |scanfacilityzip| +-----------+-------------------+---------+------

我有一个记录扫描事件的表,其中存储了第一个和最后一个事件。每晚午夜,将前一天的所有扫描事件添加到表中,删除重复项,并运行查询以删除除具有最小和最大时间戳的扫描事件之外的任何内容

问题之一是数据提供程序每45天循环一次扫描ID,因此此表没有主键。以下是表格在其最终状态下的外观示例:

|scaneventID|scandatetime       |status   |scanfacilityzip|
+-----------+-------------------+---------+---------------+
|isdijh23452|2020-01-01 13:45:12|Intake   |12345          |
|isdijh23452|2020-01-03 19:32:18|Processed|45867          |
|awgjnh09864|2020-01-01 10:24:16|Intake   |84676          |
|awgjnh09864|2020-01-02 02:15:52|Processed|84676          |
但在运行清理查询之前,它可能如下所示:

|scaneventID|scandatetime       |status   |scanfacilityzip|
+-----------+-------------------+---------+---------------+
|isdijh23452|2020-01-01 13:45:12|Intake   |12345          |
|isdijh23452|2020-01-01 13:45:12|Intake   |12345          |
|isdijh23452|2020-01-01 19:30:32|Received |12345          |
|isdijh23452|2020-01-02 04:50:22|Confirmed|12345          |
|isdijh23452|2020-01-03 19:32:18|Processed|45867          |
|awgjnh09864|2020-01-01 10:24:16|Intake   |84676          |
|awgjnh09864|2020-01-01 19:30:32|Received |84676          |
|awgjnh09864|2020-01-01 19:30:32|Received |84676          |
|awgjnh09864|2020-01-02 02:15:52|Processed|84676          |
因为有时来自供应商的数据重叠,我们对此无能为力。我当前运行以下查询以删除重复项:

DELETE   FROM scans T1
  USING       scans T2
WHERE EXTRACT(DAY FROM current_timestamp-T1.scandatetime) < 2
  AND  T1.ctid   < T2.ctid
  AND  T1.scaneventID    = T2.scaneventID
  AND  T1.scandatetime = T2.scandatetime
;
并仅保留最小/最大时间戳:

delete from scans
    where EXTRACT(DAY FROM current_timestamp-scandatetime) < 2 and
          scandatetime <> (select min(tt.scandatetime) from scans tt where tt.scaneventID = scans.scaneventID) and
          scandatetime <> (select max(tt.scandatetime) from scans tt where tt.scaneventID = scans.scaneventID)
;

然而,这张表相当大,在过去的几年里扫描了上亿次,所以扫描速度相当慢。如何加快速度?

表中有索引吗?如果不是,是否可以添加它们?scandatetime上的索引应该会有所帮助,特别是如果您将该提取更改为类似WHERE scandatetime>current_timestamp-interval“2天”的内容,以便它利用索引只查看最近的条目。是的,表中有多个索引。在scaneventID和scandatetime以及其他一些与此查询不相关的内容上。我可以尝试将timestamp子句更新为您建议的内容,这可能是一个错误boost@a_horse_with_no_name你链接的内容基本上就是我正在做的?scandatetime从scans tt中选择mintt.scandatetime@wildplasser如果您提交答复,我将欣然接受!表上有索引吗?如果不是,是否可以添加它们?scandatetime上的索引应该会有所帮助,特别是如果您将该提取更改为类似WHERE scandatetime>current_timestamp-interval“2天”的内容,以便它利用索引只查看最近的条目。是的,表中有多个索引。在scaneventID和scandatetime以及其他一些与此查询不相关的内容上。我可以尝试将timestamp子句更新为您建议的内容,这可能是一个错误boost@a_horse_with_no_name你链接的内容基本上就是我正在做的?scandatetime从scans tt中选择mintt.scandatetime@wildplasser如果您提交答复,我将欣然接受!