我有城镇表,这是主表。这个表包含这么多行,它变得如此'脏'(* 有人插入5百万行 *),我想摆脱未使用的城镇。
有3个引用表使用my town_id作为对城镇的引用。
我知道有很多城镇没有在这个表中使用,只有当town_id
没有在这3个表中找到时,我才认为它是不活动的,我想删除那个城镇(因为它没有被使用)。
打印我的故事屏幕:
如您所见,towns在这两个不同的表中使用:
- 员工
- 办公室
并且对于table * 卖主,在table城镇中存在vendor_id
,因为一个卖主可以具有多个城镇。
因此,如果towns中的vendor_id
为空,并且在这两个表中的任何一个中都找不到town_id,则可以安全地将其删除:)
我创建了一个查询,它可能会工作,但它需要太多的时间来执行,它看起来像这样:
select count(*)
from towns
where vendor_id is null
and id not in (select town_id from banks)
and id not in (select town_id from employees)
因此,基本上我说,如果vendor_is
为空,这意味着这个城镇肯定与供应商无关,同时,如果同一个城镇不在银行和员工中,那么删除它将是安全的..但查询花费了太长时间,并且从未成功执行。..因为城镇有500万行,这就是它如此肮脏的原因..
事实上,由于服务器异常终止,我无法执行给定的查询。
以下是完整的错误消息:
错误:服务器意外关闭了连接这可能意味着服务器在处理请求之前或处理请求时异常终止。
任何形式的帮助将是真棒谢谢!
3条答案
按热度按时间yc0p9oo01#
您可以使用
LEFT JOIN
来链接数据表,以便在WHERE
子句中识别数据表banks
和employee
中没有数据列的town_id
:在启动DELETE之前,可以检查表的索引。按如下方式添加索引可能很有用:
最后但并非最不重要的是,您可以在
cte
中添加LIMIT
子句,以便限制执行DELETE时删除的行数,并避免意外终止。因此,您必须多次重新启动DELETE,直到没有更多行可删除为止。lnlaulya2#
您可以在大表上尝试JOIN,它会比两个
IN
更快您也可以尝试使用
UNION ALL
并使用副本,因为它比UNION
更快最后,您可以对id和vendor_id使用组合索引,以加快查询速度
第一个问题
| 计数器|
| - -|
| 第0页|
fiddle
vohkndzv3#
诀窍是首先创建一个列表,列出所有你想保留的town_id,然后开始删除那些不存在的。在两个表中查找会让服务器的工作更加困难,所以让我们先创建一个列表。
idx_towns_town_id_where_vendor_null
是可选的,我不确定它是否会真正降低总时间,但IMHO它将有助于DELETE
操作,如果只是因为索引应该给予查询优化器一个更好的视图,什么卷预期。