where必须紧接from后且语法正确,字符串需引号、null用is判断,复合条件注意and/or优先级,索引使用依赖最左前缀和like模式。

直接说结论:WHERE 是 SELECT 的过滤开关,没它就全表扫;写错位置或逻辑表达式不合法,查询直接报错或返回意外结果。
WHERE 必须紧接在 FROM 之后,顺序错了会语法报错
MySQL 和大多数 SQL 引擎严格要求子句顺序:SELECT → FROM → WHERE → ORDER BY → LIMIT。把 WHERE 放到 ORDER BY 后面,或者插在 SELECT 和 FROM 中间,都会触发 ERROR 1064 (42000)。
-
SELECT name, price FROM products WHERE price > 10 ORDER BY price DESC✅ 正确 -
SELECT name, price FROM products ORDER BY price DESC WHERE price > 10❌ 报错:syntax near 'WHERE' -
SELECT name WHERE price > 10 FROM products❌ 报错:'WHERE' unexpected before 'FROM'
字符串、NULL、大小写:这些值比较容易出错
字符串必须用单引号包裹,且 MySQL 默认不区分大小写(除非字段用了 BINARY 或 COLLATE utf8mb4_bin);NULL 不能用 = 判断,否则永远返回 false。
-
WHERE status = 'active'✅ 字符串加引号 -
WHERE status = active❌ 变成列名或变量,报错Unknown column 'active' -
WHERE email IS NULL✅ 正确判断空值 -
WHERE email = NULL❌ 永远不成立,结果为空集 -
WHERE name = 'alice'可能匹配'Alice'(取决于 collation),别依赖它做精确匹配
复合条件要用 AND/OR,但优先级容易被忽略
AND 优先级高于 OR,不加括号时,A OR B AND C 等价于 A OR (B AND C),不是 (A OR B) AND C。线上查漏数据,十次有八次是这里括号没打。
-
WHERE type = 'user' AND (status = 'active' OR status = 'pending')✅ 明确意图 -
WHERE type = 'user' AND status = 'active' OR status = 'pending'❌ 实际执行是(type='user' AND status='active') OR status='pending',可能拉回所有 pending 记录,不管 type -
WHERE id BETWEEN 100 AND 200等价于WHERE id >= 100 AND id ,但更简洁、可读性高
WHERE 条件是否走索引,取决于字段顺序和操作符
即使写了 WHERE,也不代表能用上索引。比如对字段做函数操作(WHERE YEAR(created_at) = 2025)、或跳过复合索引的左列(索引是 (a,b,c),却只写 WHERE b = 1),都会导致全表扫描。
-
WHERE user_id = 123✅ 单列索引直接命中 -
WHERE user_id = 123 AND created_at > '2025-01-01'✅ 复合索引(user_id, created_at)完全覆盖 -
WHERE created_at > '2025-01-01'❌ 同样索引,只能用最左前缀,这里无法利用 -
WHERE name LIKE '%john'❌ 前导通配符,索引失效;LIKE 'john%'才可能走索引
真正卡住人的,往往不是语法写不对,而是条件看着合理,执行计划里却写着 type: ALL —— 那说明 WHERE 白写了,数据库正在扫全表。










