postgresql 删除除一行之外的整个表

gg58donl  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(5)|浏览(230)

假设我有一个数据库,其中的表包含200k+行。
该表有一个id为1800的固定元组。元组序列的其余部分从300k+开始。
我需要清理此表,删除所有记录,但不删除ID为1800的注册表。我提出了3种可能运行的查询类型:

DELETE FROM table WHERE id > 1800
DELETE FROM table WHERE id <> 1800
DELETE FROM table WHERE id NOT IN (1800)

我有一种感觉,第一个比其他的快,但我不确定,因为所有其他数据的id都远远大于1800。
哪一个更快,为什么?还有,如果有更快的方法来删除记录,不包括不能删除的记录,让我知道。

bnlyeluc

bnlyeluc1#

在大多数数据库中,最快的方法是:
1.将id为1800的记录选择到临时表中
1.删除原始表
1.将临时表中的数据复制到完整表中
诚然,由于触发器、约束和权限的原因,这可能是不可能的。在许多数据库中,您可以通过修改(2)来截断表,而不是删除它。
对于您最初的问题,实际删除行及其关联数据的开销将在查询中占主导地位,而您如何进行比较则无关紧要。
样本代码

create temp table saved as
    select * from t where id = 1800

truncate table t

insert into t
    select * from saved

我不确定Postgres对临时表的命名约定,但这是一个想法。

kt06eoxx

kt06eoxx2#

只要影响相同的记录,它们就会有类似的性能。
前者使用索引查找而不是更有效的全表扫描的可能性很小,但这是可以忽略的。

o75abkj4

o75abkj43#

如果不能将ID移动到新表中,您可能需要尝试分组或批量删除。有时,处理带有大量记录的事务的速度并不是最快的。这是任何数据库oracle和microsoft数据库产品都包括在内的情况。

BEGIN TRANSACTION;
DELETE FROM table WHERE id >= 0 and  id < 20000 and id != 1800;
COMMIT TRANSACTION;
BEGIN TRANSACTION;
DELETE FROM table WHERE id >= 20000 and  id < 40000 and id != 1800;
COMMIT TRANSACTION;
etc
etc
afdcj2ne

afdcj2ne4#

如果你想只保存最后一条记录,并删除所有其他记录,你可以使用下面的查询,这对我来说很有效

delete from public.table_name
WHERE lastrun_ts < (
   select MAX(lastrun_ts)
   FROM public.table_name
   ORDER BY MAX(lastrun_ts) DESC
   );
brc7rcf0

brc7rcf05#

我删除了大约80k行,除了ID为1的行需要4.5秒。
我用了:

DELETE FROM `table` WHERE id NOT IN ( 1 )

希望这对你有帮助。

相关问题