首页 > 解决方案 > 如何使用子选择优化删除查询?

问题描述

此查询需要从包含 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)

运行需要几个小时,我是否错过了一些可以加快速度的东西?

子选择本身需要几秒钟,我不明白为什么删除需要这么长时间。

标签: mysqlsqlquery-optimization

解决方案


如果你有这么多的删除要进行。我建议你:

  1. 使用将保留的数据创建新的临时表。
  2. 截断你的主表
  3. 将数据从临时表移动到主表

或者

  1. 使用将保留的数据创建新的临时表。
  2. 放下你的主桌
  3. 将您的临时表重命名为主表(不要忘记创建约束)

也为您的查询,

永远不要对大数据使用 IN 子句。而是使用更高效的存在。

基本脚本:

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;

推荐阅读