DELETE WHERE 语句的基本写法和安全前提
MySQL 中删除满足条件的数据,核心就是
DELETE FROM table_name WHERE condition。但必须强调:没有
WHERE子句的
DELETE会清空整张表,且不可回滚(除非有事务且未提交)。执行前务必确认条件能精准匹配目标行,建议先用
SELECT * FROM table_name WHERE condition验证。
WHERE 条件中常见的坑:NULL、字符串空格、大小写敏感
MySQL 的
WHERE对 NULL 值不能用
=判断,必须用
IS NULL或
IS NOT NULL;字符串字段若含前后空格,
WHERE name = 'abc'可能不命中实际值为
'abc '的记录(取决于
sql_mode和字段类型);默认情况下,
VARCHAR比较不区分大小写(受
collation影响),如需严格区分,改用
WHERE name COLLATE utf8mb4_0900_as_cs = 'AbC'。
带 JOIN 的 DELETE:语法容易写错
MySQL 支持多表删除,但语法和单表不同。想根据关联表条件删主表数据,不能直接写
DELETE FROM t1 JOIN t2 ON ... WHERE ...。正确写法是:
DELETE t1 FROM users AS t1 JOIN orders AS t2 ON t1.id = t2.user_id WHERE t2.status = 'cancelled';
注意点:
必须显式写出要删的表别名(如t1)在
DELETE后
FROM后可跟多个表,但只有前面列出的表会被删除 不支持子查询中直接引用将被删除的表(会报错
You can't specify target table for update in FROM clause)
大表删除时的性能与锁风险
对百万级以上表执行
DELETE WHERE,可能长时间持有行锁甚至表锁,阻塞业务读写。更稳妥的做法是分批删:
DELETE FROM logs WHERE created_at < '2023-01-01' LIMIT 10000;
循环执行直到影响行为 0。同时注意:
确保WHERE字段有索引,否则全表扫描 + 锁定开销极大 避免在高并发写入场景下执行大范围删除 如果只是归档旧数据,考虑用
CREATE TABLE ... SELECT提取有效数据,再重命名切换,比删更快更安全
真正危险的不是语法写错,而是没验证 WHERE 条件是否真的只命中预期的几行——线上误删往往发生在“我以为这个条件很唯一”的瞬间。
