where是sql操作的关键条件子句,必须紧接from后且仅出现一次;需注意null判断用is null、like慎用%开头、and/or优先级加括号、避免全表扫描并结合explain优化索引。

WHERE 不是可选配件,而是 SQL 操作的刹车和方向盘——没它,SELECT 会扫全表,UPDATE 和 DELETE 会误伤整列数据。用错或漏写,轻则查慢、重则删库。
WHERE 条件写在哪儿?位置错了就失效
WHERE 必须紧接在 FROM 子句之后,且只能出现一次。放在 ORDER BY 或 GROUP BY 后面,语句直接报错;嵌套子查询里要用 WHERE,也得各自独立写在对应 FROM 后面。
- ✅ 正确:
SELECT name FROM users WHERE age > 18 ORDER BY name; - ❌ 错误:
SELECT name FROM users ORDER BY name WHERE age > 18;(语法错误) - ⚠️ 注意:在
UPDATE或DELETE中漏掉WHERE,比如DELETE FROM logs;,会清空整张表——生产环境务必先用SELECT COUNT(*) FROM logs WHERE ...预估范围
NULL 值不能用 = 判断,否则查不到
MySQL 中 NULL 表示“未知”,不是值,所以任何与 NULL 的比较(=、!=、> 等)结果都是 UNKNOWN,不被 WHERE 视为真。常见现象是:明明字段显示为空,WHERE status = '' 或 WHERE status = NULL 却查不出记录。
- ✅ 查空字符串:
WHERE status = '' - ✅ 查 NULL:
WHERE status IS NULL或WHERE status IS NOT NULL - ⚠️ 注意:
WHERE status != 'active'会自动过滤掉status IS NULL的行(因为NULL != 'active'是 UNKNOWN,不满足 TRUE),如需包含 NULL,得显式写WHERE status != 'active' OR status IS NULL
LIKE 模糊匹配要防全表扫描
LIKE 看似简单,但以 % 开头(如 name LIKE '%明%')会导致索引失效,尤其在大表上极慢。真正能走索引的只有左匹配(name LIKE '张%')。
- ✅ 可走索引:
WHERE email LIKE 'admin@%'、WHERE code BETWEEN 'A001' AND 'A999' - ❌ 易拖慢查询:
WHERE title LIKE '%数据库%'、WHERE phone LIKE '%138%' - ⚠️ 注意:
_是单字符通配符,LIKE 'a_b'匹配aab、acb,但不匹配ab;若真要查字面量%或_,得用ESCAPE,例如WHERE tag LIKE '%\%%' ESCAPE '\'
多个条件混用时,AND 和 OR 优先级容易翻车
AND 优先级高于 OR。不加括号时,WHERE type = 'user' OR role = 'admin' AND status = 1 实际等价于 WHERE type = 'user' OR (role = 'admin' AND status = 1),常导致逻辑偏离预期。
- ✅ 明确意图:
WHERE (type = 'user' OR role = 'admin') AND status = 1 - ✅ 安全习惯:所有含
OR的复合条件,都用括号包裹子组 - ⚠️ 注意:
IN虽简洁,但列表过长(如上千项)可能触发性能问题或 max_allowed_packet 限制;高频等值判断建议改用临时表 + JOIN
WHERE 的真正复杂点不在语法,而在它背后隐含的数据分布、索引覆盖和执行计划。哪怕写对了条件,如果 EXPLAIN 显示 type: ALL 或 key: NULL,那筛选逻辑再准也没用——该加索引的地方,一个都不能少。











