Mysql 如何使用子选择优化删除查询?

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

这个查询需要从一个包含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 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);