and要求所有条件同时为真,or只需任一条件为真;混合使用必须加括号明确逻辑顺序;or易导致索引失效,应优先考虑union或联合索引;含null判断需遵循三值逻辑并显式处理。

AND 和 OR 的逻辑行为必须分清
AND 要求所有条件同时为真,OR 只要任一条件为真就成立。这不是“语法差异”,而是查询结果是否符合业务预期的根本分水岭。
比如:SELECT * FROM users WHERE age > 18 AND city = 'Beijing' 找的是“又成年、又在北京”的人;而 SELECT * FROM users WHERE age > 18 OR city = 'Beijing' 找的是“成年者”或“北京人”——哪怕是个 16 岁的北京学生也会被拉进来。
混合使用时括号不是可选项,是必选项
MySQL 中 AND 优先级远高于 OR,不加括号等于把逻辑交给编译器猜,结果往往和你脑内想的不一样。
-
WHERE age > 18 OR city = 'Beijing' AND salary > 5000实际等价于WHERE age > 18 OR (city = 'Beijing' AND salary > 5000),不是你想要的“(年龄>18 或 城市=北京)且薪资>5000” - 正确写法应为:
WHERE (age > 18 OR city = 'Beijing') AND salary > 5000 - 再比如查“年龄60,且状态为 active”,必须写成:
WHERE (age 60) AND status = 'active';漏括号就会变成age 60 AND status = 'active'),完全跑偏
性能陷阱:OR 容易让索引失效
当 OR 连接的多个条件涉及不同字段(如 d_id = 1001 OR sex = '男'),MySQL 很难高效利用索引,尤其在大表上可能触发全表扫描。这不是写法错误,而是引擎限制。
- 如果字段有独立索引但没联合索引,
OR基本无法走索引优化 - 替代方案之一是用
UNION拆开:(SELECT * FROM employee WHERE d_id = 1001) UNION (SELECT * FROM employee WHERE sex = '男'),让每个子查询独立走索引 - 更优解是建覆盖型联合索引(如
(d_id, sex)),再配合IN或重写逻辑,但前提是业务允许条件收敛
别忽略 NULL 和空字符串的干扰
用 AND 或 OR 连接含 IS NULL 的判断时,容易误以为逻辑对称。实际上 NULL = 'value' 返回 UNKNOWN,不是 FALSE,会直接影响 AND/OR 结果。
- 比如:
WHERE status = 'active' OR level IS NULL—— 如果某行status是NULL,整个表达式不会因status = 'active'不成立就跳过,但也不会直接判假,得看三值逻辑规则 - 稳妥做法是显式处理:
WHERE (status = 'active' OR status IS NULL) AND (level IS NULL OR level > 0) - 测试时务必用真实含 NULL 数据验证,别只靠“看起来应该对”
括号不是为了好看,是防止逻辑被优先级悄悄改写;OR 不是不能用,但每加一个都要问一句:这个条件能不能走索引?有没有 NULL 暗坑?










