AND 优先级高于 OR,混用时必须加括号明确逻辑分组,如 (A OR B) AND C;同字段多值 OR 应改用 IN 以避免索引失效;AND 连接范围条件时仅能高效使用一个索引,需按等值在前、范围在后建复合索引。

AND 和 OR 在 WHERE 子句里怎么连用才不出错
MySQL 中 AND 优先级高于 OR,不加括号容易查出意外结果。比如写 WHERE status = 'active' OR type = 'vip' AND score > 80,实际等价于 WHERE status = 'active' OR (type = 'vip' AND score > 80),而不是你直觉想表达的「活跃用户或 VIP 且高分」。
- 所有涉及
AND和OR混用的条件,必须用圆括号明确逻辑分组 - 避免靠记忆优先级来写条件,括号不增加开销,但能防止线上查错数据
- 如果逻辑是「(A 或 B) 且 C」,一定要写成
(status = 'active' OR type = 'vip') AND score > 80
多个 OR 条件导致索引失效怎么办
当写成 WHERE type = 'user' OR type = 'admin' OR type = 'guest' 这类“同字段多值 OR”,MySQL 很可能放弃使用 type 上的索引,转为全表扫描——尤其在数据量大时性能骤降。
- 优先改用
IN:WHERE type IN ('user', 'admin', 'guest'),优化器更易走索引 - 若必须用
OR(比如跨字段),可考虑UNION ALL拆查询,每部分独立走索引 - 注意
OR中只要有一个分支无法用索引(如对字段做函数操作),整个 WHERE 可能退化
AND 连接多个范围条件时索引还能用吗
比如 WHERE created_at > '2024-01-01' AND score BETWEEN 60 AND 90,即使两个字段都有索引,MySQL 通常只能用上其中一个(一般是左边那个),另一个变成过滤条件而非索引查找。
- 复合索引顺序很重要:把区分度高、常用于等值查询的列放前面,范围查询列放后面
- 例如高频查询是
WHERE user_id = ? AND created_at > ?,就建(user_id, created_at)索引 -
AND后面跟多个BETWEEN/>/时,只有最左的范围条件能命中索引,后面的都失效
NULL 值会让 AND/OR 行为变诡异
NULL 参与逻辑运算结果是 UNKNOWN,不是 TRUE 或 FALSE。所以 WHERE status = 'active' AND deleted IS NULL 中,只要某行 deleted 是 NULL,整条就满足;但 WHERE status = 'active' OR deleted = 0 中,若 deleted 是 NULL,deleted = 0 返回 UNKNOWN,而 OR 遇到 UNKNOWN 不会跳过,整行仍不匹配。
- 判断 NULL 必须用
IS NULL或IS NOT NULL,不能用= NULL -
OR条件里混入IS NULL时,要确认是否真想包含这些行,否则容易漏数据 - 聚合函数如
COUNT()、SUM()默认忽略NULL,但AND/OR不忽略,这点常被忽略









