除了一行外,删除整个表

Mur*_*foX 3 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)
Run Code Online (Sandbox Code Playgroud)

我觉得第一个比其他人更快,但我不确定,因为所有其他数据的ID都大于1800.

哪一个更快,为什么?此外,如果有更快的方法删除不能删除的记录,请告诉我.

Gor*_*off 6

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

  1. 选择ID为1800的记录到临时表中
  2. 放下原始表格
  3. 将临时表中的数据复制到完整表中

不可否认,由于触发器,约束和权限,这可能无法实现.在许多数据库中,您可以通过修改(2)截断表而不是删除表来执行类似的操作.

至于你的原始问题,实际删除行的开销和与它们相关的数据将主导查询.你如何进行比较是无关紧要的.

示例代码

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

truncate table t

insert into t
    select * from saved
Run Code Online (Sandbox Code Playgroud)

我不确定临时表的Postgres命名约定,但这是个主意.

  • 虽然这很快,但它使用DDL语句而不是DML语句来实现,如果您不得不关注表间依赖关系,这可能是灾难性的.我倾向于在`id`上添加一个索引(如果它已经不存在)并且如果你想要更安全的数据一致性那么做`delete`; 因为,要运行删除,您需要首先选择记录(因此索引会加快部分操作).但是,如果原始速度是您唯一关注的问题,那么这可能是最快的方法. (2认同)

Qua*_*noi 6

只要那些影响相同的记录,那些将具有相似的性能.

前者有可能使用索引搜索而不是更有效的全表扫描,但它可以忽略不计.