如何优化这个sql删除语句
我有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);
但它非常慢,需要很多时间,有一些更好的方法到这个删除语句?
如果这可以帮助我可以假设表2比表3有更多的数据。
我使用的数据库是 Apache Derby。
感谢您的帮助。
I have 3 tables, the first one, table1, has as primary key the id column, the second table (table2) has a column table1_id that refer as foreign key to the table1.id, the third table (table3) has, as table2, a column table1_id that refer as foreign key to table1.id.
I have to delete from table1 all the rows where table1.id is not in table2.table1_id and not in table3.table1_id
now i am using this query:
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);
but it is very slow, it takes a lot of time, there are some better approach to this delete statement?
If this can help i can assume that table2 has more data that table3.
The database i am using is Apache Derby.
Thanks for the help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
假设您已经涵盖了明显的内容(为
table1.id
、table2.table1_id
和table3.table1_id
创建的索引),您不需要执行完全外连接只是为了测试某个键是否在另一个表中,您可以在您的情况下使用子查询和exists()
- 或notexists()
。由于您只是测试存在性,因此可以使用以下模式:
Assuming you got the obvious covered (indices created for
table1.id
,table2.table1_id
andtable3.table1_id
), you don't need to perform full outer joins just to test if a key is in another table, you can use subqueries andexists()
-- ornot exists()
in your case.And since you're only testing for existence, you can use the following pattern:
您知道要删除多少行吗?我同意@Blindy,如果德比支持的话,在你的情况下不存在可能会更好(我不了解德比,所以我不能肯定地说)。但是,如果有大量记录被删除,您可能需要分批执行此操作。无论查询效率如何,删除 10,000,000 条记录都需要很长时间。在一次执行 1000 个的循环中删除它们通常对数据库来说更好,因为在整个过程完成时不会使用表锁并锁定用户。再说一遍,我不了解 Derby,所以我不知道 Derby 是否属实,但它肯定有助于在我熟悉的大多数数据库中进行大量删除。
Do you know how many rows you are deleting? I agree with @Blindy, that not exists would probably be better in your case if Derby supports it (I don't know Derby so I can't say for sure). However, if there are a lot of records being deleted, you might want to do this in batches. Deleting a 10,000,000 records is going to take a long time no matter how efficent the query is. Deleting them in a loop that does 1000 at a time is often better for the database as it won't take a table lock and lock out users while the whole process is done. Again I don't know Derby, so I don't know if this is true of Derby, but it certainly would help a large delete in most databases I am familiar with.