MySQL如何高效快速删除数据?现有DELETE语句执行过慢求优化方案
原SQL慢的核心原因
- 错误使用
GROUP_CONCAT拼接ID:将符合条件的ID拼成单个字符串传入IN子句,数据库无法识别为离散的ID集合,不会走id字段的索引,强制触发全表扫描;同时GROUP_CONCAT有默认长度限制,超出后ID会被截断,大概率会导致漏删或者错删数据。 - 嵌套子查询+
IN的写法本身效率偏低,额外增加了一次子查询结果的匹配开销。
高效实现方案
方案1:多表关联DELETE(最优,性能最高)
直接用关联逻辑匹配要删除的行,不需要额外子查询,语法如下:
DELETE N FROM table_a N INNER JOIN table_b E ON N.form_id = E.form_id AND N.element_id = E.element_id WHERE N.option_value = 0 AND E.element_type IN ('checkbox','radio','select')
这个写法直接定位符合条件的table_a行删除,不需要额外处理ID集合,性能比原写法高数倍。
方案2:修正子查询写法(如果不习惯关联删除可以用)
去掉GROUP_CONCAT,直接让子查询返回ID集合,数据库可以正常走id索引:
DELETE FROM table_a WHERE id IN ( SELECT N.id FROM table_a N INNER JOIN table_b E ON N.form_id=E.form_id AND N.element_id=E.element_id WHERE N.option_value=0 AND E.element_type IN('checkbox','radio','select') )
注意:部分数据库(比如MySQL)不允许在子查询里直接引用要删除的同一张表,可能会报错,更推荐使用方案1。
额外性能优化建议
可以给关联字段和过滤字段加联合索引,进一步提升执行速度:
- 给
table_a加联合索引:(form_id, element_id, option_value, id),覆盖关联、过滤和返回ID的所有需求 - 给
table_b加联合索引:(form_id, element_id, element_type),覆盖关联和类型过滤的需求
内容的提问来源于stack exchange,提问作者Noufal netspective
相关产品推荐
相关产品推荐

