You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL删除查询持续运行无报错问题求助

兄弟,看你这DELETE语句卡着跑不动,我太懂这种滋味了!结合你给的表数据量和未写完的SQL,大概率是嵌套子查询的性能坑加上可能没建索引的问题,给你捋捋怎么解决:

先搞清楚核心问题

你的SQL应该是想删除没有在liste_des_cours_has_cours关联表里出现过的cours记录对吧?但你用的多层嵌套IN子查询在12万级数据量下会特别慢:

  • 多层(select * from cours)会生成无索引的临时表,数据库要反复扫描这些临时表
  • NOT IN子查询在处理大数据集时,执行计划通常是低效的嵌套循环,相当于每条cours记录都要跑一遍子查询
  • 如果关联字段没建索引,还会触发全表扫描,12万×12万的扫描量肯定卡到天荒地老
第一步:先补全索引(最关键!)

先检查这两个索引有没有:

  • 给cours表的Id_cours加索引(如果它不是主键的话,主键自带索引):
    CREATE INDEX idx_cours_id ON cours(Id_cours);
    
  • 给liste_des_cours_has_cours表的关联字段(对应cours.Id_cours的字段,比如cours_Id_cours)加索引:
    CREATE INDEX idx_lchc_cours_id ON liste_des_cours_has_cours(cours_Id_cours);
    
第二步:用更高效的写法替代嵌套子查询

推荐用LEFT JOIN替代NOT IN,不仅性能好,还能避免NOT IN遇到NULL值的坑:

MySQL写法:

DELETE c
FROM cours c
LEFT JOIN liste_des_cours_has_cours lchc 
  ON c.Id_cours = lchc.cours_Id_cours  -- 这里替换成你实际的关联字段名
WHERE lchc.cours_Id_cours IS NULL;

PostgreSQL写法(如果用的是PG):

DELETE FROM cours
WHERE Id_cours NOT IN (
  SELECT DISTINCT cours_Id_cours 
  FROM liste_des_cours_has_cours
  WHERE cours_Id_cours IS NOT NULL
);

(加DISTINCT是因为关联表里可能有重复的ID,去重后子查询结果更小,执行更快)

第三步:可选:分批删除避免锁表

如果一次性删除的记录太多,可能会锁表影响业务,建议分批删:

WHILE EXISTS (
  SELECT 1 FROM cours c
  LEFT JOIN liste_des_cours_has_cours lchc 
    ON c.Id_cours = lchc.cours_Id_cours
  WHERE lchc.cours_Id_cours IS NULL
) DO
  DELETE c
  FROM cours c
  LEFT JOIN liste_des_cours_has_cours lchc 
    ON c.Id_cours = lchc.cours_Id_cours
  WHERE lchc.cours_Id_cours IS NULL
  LIMIT 1000;  -- 每次删1000条,根据你的数据库性能调整数量
END WHILE;

按这个步骤来,应该很快就能跑完了!

内容的提问来源于stack exchange,提问作者firestormde3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:25:43