如何优化这个sql delete语句

时间:2011-09-22 15:06:50

标签: sql query-optimization derby delete-row

我有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有更多数据表3。

我使用的数据库是Apache Derby。

感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

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

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

where not exists ( select top 1 1 from... where... )

答案 1 :(得分: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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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