2013-10-28 73 views
0

我正在使用此查询从一个表中删除唯一记录。SUbstiute SubQuery从表中删除记录

DELETE FROM TABLE 1 WHERE ID NOT IN (SELECT ID form TABLE 2) 

但问题是,两个表都有数以百万计的记录,并且使用子查询会很慢。

任何人都可以告诉我任何选择。

+0

取决于您的索引策略。 – eggyal

回答

1
Delete t1 
from table_1 t1 
left join table_2 t2 on t1.id = t2.id 
where t2.id is null 
+1

MySQL不会优化'NOT IN'反连接的效率与'OUTER JOIN/IS NULL'效率一样吗?参见[@Quassnoi的分析](http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/):“*算法是实际上是一样的......并且查询在同一时间完成。“。 – eggyal

0

子查询是真的很慢infact joins存在!

DELETE table1 
FROM table1 LEFT JOIN table2 ON table1.id = table2.id 
WHERE table2.id is null 
0

从表格中删除数百万条记录总是会有性能问题;你需要检查,如果表中有 - 1.限制 2.触发器,& 3.指数

就可以了。这些东西会让你的删除更慢...

请在此活动前禁用它们。您还应该检查“待删除”记录与整个表格卷的比率。如果要删除的记录数量超过整个表格数量的50%,那么您应该考虑以下方法 -

  1. 创建一个包含要从原始表中保留的记录的临时表。
  2. 放下原始表格。
  3. 将临时表重命名为原始表。

在开始上述方法之前,请确保您拥有依赖于此原始表的每个对象的定义副本,例如约束,索引,触发器等。您可能还需要检查您要删除的表格有任何孩子。

完成此活动后,您可以再次启用约束,索引,触发器!

谢谢, Aditya

+0

禁用索引时要小心:有些可能会大大加快此操作。禁用约束和触发器时还要小心:它们可能对维护数据一致性至关重要。 – eggyal

+0

感谢您的评论。看看这个问题,我认为用户想要删除数百万条记录,并且删除这么大的卷并不是每天都会发生的。这就是我认为它是一次性活动并且建议禁用索引和约束的原因 –

+0

但是索引在相应表格中的'id'上将会有*戏剧性*的帮助。禁用这些索引将是一个可怕的想法。 – eggyal