除了一行外,删除整个表

时间:2013-01-16 19:21:06

标签: 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)

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

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

4 个答案:

答案 0 :(得分:6)

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

  1. 选择ID为1800的记录到临时表中
  2. 删除原始表格
  3. 将临时表中的数据复制到完整表格
  4. 不可否认,由于触发器,约束和权限,这可能无法实现。在许多数据库中,您可以通过修改(2)来截断表而不是删除它来执行类似的操作。

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

    示例代码

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

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

答案 1 :(得分:6)

只要那些影响相同的记录,那些就会有相似的表现。

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

答案 2 :(得分:3)

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

答案 3 :(得分:0)

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

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