我有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 回答
假设你有明显的覆盖(为
table1.id
,table2.table1_id
和table3.table1_id
创建的索引),你不需要执行完全外连接只是为了测试一个键是否在另一个表中,你可以使用子查询和exists()
- 或not exists()
在你的案件 .由于您只是测试存在,您可以使用以下模式:
你知道你要删除多少行?我同意@Blindy,如果德比支持它,那么在你的情况下不存在可能会更好(我不知道德比,所以我不能肯定地说) . 但是,如果有大量记录被删除,您可能希望批量执行此操作 . 无论查询多么有效,删除10,000,000条记录都需要很长时间 . 在一次执行1000次的循环中删除它们对于数据库来说通常更好,因为它不会占用表锁并在整个过程完成时锁定用户 . 我再也不知道Derby,所以我不知道Derby是否属实,但它肯定会帮助我熟悉的大多数数据库中的大量删除 .