Sql 删除除一行以外的整个表

Sql 删除除一行以外的整个表,sql,postgresql,optimization,sql-delete,Sql,Postgresql,Optimization,Sql Delete,假设我有一个数据库,其中的表包含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) 我有一种感觉,第一个比其他的更快,但我不

假设我有一个数据库,其中的表包含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


哪一个更快,为什么?此外,如果有更快捷的方法删除记录(无法删除的记录除外),请告诉我。

大多数数据库中最快捷的方法是:

将id为1800的记录选择到临时表中 放下原来的桌子 将临时表中的数据复制到完整表中 诚然,由于触发器、约束和权限的原因,这可能是不可能的。在许多数据库中,您可以通过修改2来截断表而不是删除表来执行类似的操作

至于您最初的问题,实际删除行及其相关数据的开销将主导查询。你如何进行比较是无关紧要的

示例代码

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

truncate table t

insert into t
    select * from saved

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

只要它们影响相同的记录,它们就会有类似的性能


前者使用索引查找的可能性很小,而不是更高效的完整表扫描,但可以忽略不计。

如果无法将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

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

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

最快的可能是将您想要的一条记录复制到一个临时表中,截断该表,然后将一条记录插回,除非查询优化器完全是垃圾,这是不可能的,三条记录完全相同。这取决于。如果id是主键或索引字段,则这三个查询的性能相当。其他:根据id域的索引和基数,任何事情都会发生。您可能对密切相关的答案和答案感兴趣。是否涉及外键?如果是这样的话,这也会极大地影响性能。无论如何,如果没有外键,复制记录并截断可能会起作用。如果有外键,那么删除所有其他行是一种方法,遗憾的是,这相当缓慢。另外,如果有FK,那么请确保它们在引用行上有索引。谢谢您的回答。不过,我会接受@GordonLinoff answer,因为它提供了一种不同的技术来删除记录。虽然这很快,但它是用DDL语句而不是DML语句来完成的,如果您不得不考虑表间依赖性,这可能会带来灾难性的后果。我倾向于在id上添加索引,如果它还不存在,如果您想要更安全的数据一致性,则执行删除操作;因为,要运行delete,您需要首先选择记录,以便索引加快部分操作。但是,如果您只关心原始速度,那么这可能是最快的方法。截断几乎总是比删除并重新创建表好。如果有外键等怎么办?截断要简单得多,速度与删除和重新创建表一样快。如果不是更快