我有两张桌子.我们称之为KEY和VALUE.
KEY很小,约有1.000.000条记录.
VALUE很大,比如1.000.000.000记录.
在它们之间存在一个连接,使得每个KEY可能具有许多VALUES.它不是外键,但基本上是相同的含义.
DDL看起来像这样
create table KEY (
key_id int,
primary key (key_id)
);
create table VALUE (
key_id int,
value_id int,
primary key (key_id, value_id)
);
Run Code Online (Sandbox Code Playgroud)
现在,我的问题.VALUE中大约一半的key_id已从KEY中删除,我需要以有序的方式删除它们,而两个表仍然处于高负荷状态.
这很容易做到
delete v
from VALUE v
left join KEY k using (key_id)
where k.key_id is null;
Run Code Online (Sandbox Code Playgroud)
但是,因为它不允许limit有多表删除我不喜欢这种方法.这样的删除需要几个小时才能运行,这使得无法限制删除.
另一种方法是创建游标以查找所有缺少的key_ids并逐个删除它们.这似乎非常缓慢,有点倒退.
还有其他选择吗?一些可以帮助的好技巧?
Bil*_*win 23
试图在一个事务中删除如此多数据的任何解决方案都会压倒回滚段并导致很多性能问题.
pt-archiver是一个很好的帮助工具.它尽可能高效地对中等大小的行执行增量操作. pt-archiver可以根据选项复制,移动或删除行.
该文档包含删除孤立行的示例,这正是您的场景:
pt-archiver --source h=host,D=db,t=VALUE --purge \
--where 'NOT EXISTS(SELECT * FROM `KEY` WHERE key_id=`VALUE`.key_id)' \
--limit 1000 --commit-each
Run Code Online (Sandbox Code Playgroud)
执行此操作将花费更长时间来删除数据,但不会使用太多资源,也不会中断现有数据库上的服务.我成功地使用它来清除数亿行过时的数据.
pt-archiver是Percona Toolkit for MySQL的一部分,这是一套免费的(GPL)脚本,可以帮助MySQL和兼容数据库完成常见任务.
这个有限制怎么办?
delete x
from `VALUE` x
join (select key_id, value_id
from `VALUE` v
left join `KEY` k using (key_id)
where k.key_id is null
limit 1000) y
on x.key_id = y.key_id AND x.value_id = y.value_id;
Run Code Online (Sandbox Code Playgroud)
直接来自MySQL文档
如果要从大型表中删除许多行,则可能会超出InnoDB表的锁定表大小.要避免此问题,或者只是为了最小化表保持锁定的时间,以下策略(根本不使用DELETE)可能会有所帮助:
选择不要删除的行到与原始表具有相同结构的空表中:
Run Code Online (Sandbox Code Playgroud)INSERT INTO t_copy SELECT * FROM t WHERE ... ;使用RENAME TABLE以原子方式移动原始表并将副本重命名为原始名称:
Run Code Online (Sandbox Code Playgroud)RENAME TABLE t TO t_old, t_copy TO t;删除原始表:
Run Code Online (Sandbox Code Playgroud)DROP TABLE t_old;在RENAME TABLE执行时,没有其他会话可以访问所涉及的表,因此重命名操作不会受到并发问题的影响.请参见第12.1.9节"RENAME TABLE语法".
所以在你的情况下,你可以这样做
INSERT INTO value_copy SELECT * FROM VALUE WHERE key_id IN
(SELECT key_id FROM `KEY`);
RENAME TABLE value TO value_old, value_copy TO value;
DROP TABLE value_old;
Run Code Online (Sandbox Code Playgroud)
根据他们在这里写的内容, RENAME操作很快,记录数量也不会影响它.
| 归档时间: |
|
| 查看次数: |
18390 次 |
| 最近记录: |