MySQL Select工作正常,但Delete会根据GROUP BY的位置无限期挂起

时间:2019-05-09 14:55:30

标签: mysql sql

select * from table1 where ID in (
    select min(a.ID) from (select * from table1) a group by id_x, id_y, col_z having count(*) > 1)

以上查询在2.2秒内运行,返回四个结果。现在,当我将select *更改为delete时,它会无限期挂起。

delete from table1 where ID in (
    select min(a.ID) from (select * from table1) a group by id_x, id_y, col_z having count(*) > 1)

如果我在别名选择查询中移动group by子句的位置,它将不再挂起。

delete from table1 where ID in (
    select a.ID from (select min(ID) from table1 group by id_x, id_y, col_z having count(*) > 1) a)

为什么挂起?即使(select * from table1)拉动了数百万条记录,查询似乎也没有停止执行数小时。有人可以解释是什么困扰了查询吗?这使我感到困惑,因为选择查询工作正常,而删除查询挂起。

编辑: 我在这里的重点是它为什么挂起。我已经发布了可行的解决方法。但是,为了开发预防系统,我需要找到根本原因。

2 个答案:

答案 0 :(得分:0)

使用JOIN代替WHERE ID IN (SELECT ...)

DELETE t1
FROM table1 AS t1
JOIN (
    SELECT MIN(id) AS minId
    FROM table1
    GROUP BY id_x, id_y, col_z 
    HAVING COUNT(*) > 1) AS t2
ON t1.id = t2.minId

我认为您的查询没有得到优化,因为每次删除后都必须重新计算子查询,因为删除一行可能会更改该组的MIN(id)。使用JOIN只需进行一次分组和聚合。

答案 1 :(得分:0)

尝试一下:

delete t
    from table1 t join
         (select min(id) as min_id
          from table1
          group byid_x, id_y, col_z
          having count(*) >= 2
         ) tt
         on tt.min_id = t.id;

也就是说,您可能不想仅删除最小ID。我猜您想保留最新的ID。如果是这样:

delete t
    from table1 t left join
         (select max(id) as max_id
          from table1
          group byid_x, id_y, col_z
          having count(*) >= 2
         ) tt
         on tt.max_id = t.id
    where tt.max_id is null;