Mysql 如何使用子选择优化删除查询?
这个查询需要从一个包含2000万行的表中删除超过1700万行Mysql 如何使用子选择优化删除查询?,mysql,sql,query-optimization,Mysql,Sql,Query Optimization,这个查询需要从一个包含2000万行的表中删除超过1700万行 DELETE FROM statements WHERE agreement_id IN (SELECT id FROM agreements WHERE created < DATE_SUB(CURDATE(), INTERVAL 6 MONTH)); DELETE FROM agreements WHERE created < DATE_SUB(CURDATE(), INTERVAL 6
DELETE
FROM statements
WHERE agreement_id IN
(SELECT id
FROM agreements
WHERE created < DATE_SUB(CURDATE(), INTERVAL 6 MONTH));
DELETE
FROM agreements
WHERE created < DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
跑步需要几个小时,我是否错过了一些可以加快速度的东西
子选择本身需要几秒钟的时间,我不明白为什么删除要花这么长时间。如果要执行这么多的删除操作。 我建议你: 使用将保留的数据创建新的临时表。 截断主表 将数据从临时表移动到主表 或 使用将保留的数据创建新的临时表。 放下你的主桌 将临时表重命名为主表不要忘记创建约束 还有你的问题 不要在大数据中使用IN子句。相反,存在性能更高的use 基本脚本:
CREATE TABLE tmp_statements as
SELECT * FROM statements s where exists
(
select 1 FROM agreements a
WHERE
created < DATE_SUB(CURDATE(), INTERVAL 6 MONTH AND
s.agreement_id = a.agreement_id
));
DROP TABLE statements;
RENAME TABLE tmp_statements TO statements ;
--DONT FORGET TO RECREATE CREATE YOUR INDEXES, CONSTRAINTS;
尝试重写要使用的第一条语句 对于第二种方法,如果尚未创建协议,则创建协议索引
CREATE INDEX agreements_id_created
ON agreements
(id,
created);
CREATE INDEX agreements_created
ON agreements
(created);
使用多表删除,而不是通常效率低下的SELECT 本文讨论了几种用于大型删除的技术
要删除85%的表,最好用保留的15%构建一个新表,然后将表交换到位。更多信息请参见上面的链接。我们可以了解statements表的结构吗,也许您应该制定一致的id和索引。每个查询优化问题都应该包括查询中引用的每个表的SHOW CREATE table输出。帮助我们帮助您-不要让我们猜测您当前拥有哪些数据类型和索引。阅读本文时,我对此表示怀疑。我需要为本地开发人员构建一个最小的数据集,在尝试了其他方法之后,我采用了这种方法。到目前为止,这是最快也有点脏的方法。@stefgosselin-在现实生活中,有时用草包也可以。我想你们谈论的是复制行以保留方法?正如我在上面的评论中所写的,谁链接到了相同的方法,读到这篇文章时,我表示怀疑。我需要为本地开发人员构建一个最小的数据集,在尝试了其他方法之后,我采用了这种方法。到目前为止,这是最快也有点脏的方法。谢谢
CREATE INDEX agreements_created
ON agreements
(created);