首页 文章

如何优化这个sql delete语句

提问于
浏览
1

我有3个表,第一个,table1,作为主键的id列,第二个表(table2)有一个列table1_id,作为table1.id的外键引用,第三个表(table3)有,作为table2 ,一个列table1_id,它作为table1.id的外键引用 .

我必须从table1中删除table1.id不在table2.table1_id中而不在table3.table1_id中的所有行

现在我正在使用此查询:

DELETE FROM table1
WHERE  table1.id IN (SELECT table1.id
                     FROM   (table2
                             RIGHT OUTER JOIN table1
                               ON table2.table1_id = table1.id)
                            LEFT OUTER JOIN table3
                              ON table3.table1_id = table1.id
                     WHERE  table2.table1_id IS NULL
                            AND table3.table1_id IS NULL);

但它很慢,需要花费很多时间,还有一些更好的方法来删除这个删除语句?

如果这可以帮助我可以假设table2有更多数据表table3 .

我使用的数据库是Apache Derby .

谢谢您的帮助 .

4 回答

  • 1

    假设你有明显的覆盖(为 table1.idtable2.table1_idtable3.table1_id 创建的索引),你不需要执行完全外连接只是为了测试一个键是否在另一个表中,你可以使用子查询和 exists() - 或 not exists() 在你的案件 .

    由于您只是测试存在,您可以使用以下模式:

    where not exists ( select top 1 1 from... where... )
    
  • 1
    DELETE     table1
    FROM       table1
    LEFT JOIN  table2 ON table1.id = table2.table1_id
    LEFT JOIN  table3 ON table1.id = table3.table1_id
    WHERE table2.table1_id IS NULL
      AND table3.table1_id IS NULL
    
  • 0

    你知道你要删除多少行?我同意@Blindy,如果德比支持它,那么在你的情况下不存在可能会更好(我不知道德比,所以我不能肯定地说) . 但是,如果有大量记录被删除,您可能希望批量执行此操作 . 无论查询多么有效,删除10,000,000条记录都需要很长时间 . 在一次执行1000次的循环中删除它们对于数据库来说通常更好,因为它不会占用表锁并在整个过程完成时锁定用户 . 我再也不知道Derby,所以我不知道Derby是否属实,但它肯定会帮助我熟悉的大多数数据库中的大量删除 .

  • 0
    DELETE from table1
    WHERE 
       table1_id NOT IN (SELECT table1_id FROM table2)
       AND
       table1_id NOT IN (SELECT table1_id FROM table3)
    

相关问题