PostgreSQL删除除最旧记录之外的所有记录
我有一个PostgreSQL数据库,在多个设备名称上有多个objectid条目,但每个条目都有一个唯一的时间戳.该表看起来像这样:
address | devicename | objectid | timestamp --------+------------+---------------+------------------------------ 1.1.1.1 | device1 | vs_hub.ch1_25 | 2012-10-02 17:36:41.011629+00 1.1.1.2 | device2 | vs_hub.ch1_25 | 2012-10-02 17:48:01.755559+00 1.1.1.1 | device1 | vs_hub.ch1_25 | 2012-10-03 15:37:09.06065+00 1.1.1.2 | device2 | vs_hub.ch1_25 | 2012-10-03 15:48:33.93128+00 1.1.1.1 | device1 | vs_hub.ch1_25 | 2012-10-05 16:01:59.266779+00 1.1.1.2 | device2 | vs_hub.ch1_25 | 2012-10-05 16:13:46.843113+00 1.1.1.1 | device1 | vs_hub.ch1_25 | 2012-10-06 01:11:45.853361+00 1.1.1.2 | device2 | vs_hub.ch1_25 | 2012-10-06 01:23:21.204324+00 我想删除除odjectid和devicename之外的所有条目.在这种情况下,我想删除所有,但: 1.1.1.1 | device1 | vs_hub.ch1_25 | 2012-10-02 17:36:41.011629+00 1.1.1.2 | device2 | vs_hub.ch1_25 | 2012-10-02 17:48:01.755559+00 有办法吗?或者是否可以将“objectid和devicename”中最旧的条目选择到临时表中? 解决方法
为了提炼所描述的结果,这可能是最简单和最快的:
SELECT DISTINCT ON (devicename,objectid) * FROM tbl ORDER BY devicename,objectid,ts DESC; 细节和解释in this related answer. 从您的示例数据中,我得出结论,您将删除原始表的大部分内容.它可能更快到 我还强烈建议在您的表中添加一个代理主键,最好是 BEGIN; CREATE TEMP TABLE tmp_tbl ON COMMIT DROP AS SELECT DISTINCT ON (devicename,ts DESC; TRUNCATE tbl; ALTER TABLE tbl ADD column tbl_id serial PRIMARY KEY; -- or,if you can afford to drop & recreate: -- DROP TABLE tbl; -- CREATE TABLE tbl ( -- tbl_id serial PRIMARY KEY --,address text --,devicename text --,objectid text --,ts timestamp); INSERT INTO tbl (address,devicename,ts) SELECT address,ts FROM tmp_tbl; COMMIT; 在交易中完成所有操作,以确保您不会在中途失败. 只要您的 SET temp_buffers = 1000MB; 所以你不要浪费你通常不需要temp_buffers的RAM.必须在会话中第一次使用临时对象之前.更多信息,请参见this related answer. 此外,由于INSERT在事务中遵循TRUNCATE,因此在Write Ahead Log上将很容易 – 提高性能. 考虑使用CREATE TABLE AS替代路由: > What causes large INSERT to slow down and disk usage to explode? 唯一的缺点:你需要在桌子上独家锁定.这可能是具有大量并发负载的数据库中的问题. 最后,永远不要使用时间戳作为列名.它是每个SQL标准中的reserved word和PostgreSQL中的类型名称.您可能已经注意到我将该列重命名为ts. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |