mysql中and优先于or,混合逻辑必须显式加括号;in替代多个or更安全高效;联合索引需遵循最左前缀原则;like仅前缀匹配可用索引;类型隐式转换会导致索引失效。

AND 和 OR 混用时逻辑优先级容易出错
MySQL 默认按 AND 优先于 OR 执行,不加括号极易查出意外结果。比如 WHERE type = 'user' OR type = 'admin' AND status = 1 实际等价于 WHERE type = 'user' OR (type = 'admin' AND status = 1),而不是你本意的「type 是 user 或 admin,且 status = 1」。
解决办法只有一条:所有混合逻辑必须显式加括号。
-
(type = 'user' OR type = 'admin') AND status = 1—— 先分组再约束 -
NOT (age > 18 AND city = 'bj')—— 否定整个组合,NOT age > 18只是否定比较本身 - 哪怕看起来“显然”,也别依赖脑内运算顺序,写 SQL 就是写给机器看的,不是给人猜的
IN 替代多个 OR 更简洁安全
当要匹配多个离散值(如城市列表、状态码),用 IN 比堆砌 OR 更可靠、更易读、也更利于优化器选择索引。
例如查北京、上海、广州用户:
- ❌ 不推荐:
city = '北京' OR city = '上海' OR city = '广州' - ✅ 推荐:
city IN ('北京', '上海', '广州') -
IN支持子查询,但大数据量时注意性能;若右侧是常量列表,MySQL 会自动排序并二分查找 - 注意:
NULL在IN中永远不匹配,col IN (1, 2, NULL)等价于col IN (1, 2),不会返回col IS NULL的行
联合索引下多条件顺序直接影响是否走索引
写了 WHERE a = ? AND b > ? AND c = ?,但索引是 (a, b, c),那只有 a 和 b 能用于查找,c 不参与索引查找(只可能覆盖或排序)。
- 等值条件(
=、IN)必须从最左开始连续出现,中间不能断 - 一旦出现范围条件(
>、BETWEEN、LIKE 'abc%'),其右侧字段就失效 - 高频必查字段(如
tenant_id、user_id)必须放最左,别被“区分度高”误导——索引生效的前提是它出现在 WHERE 开头 - 验证是否真用了索引?必须看
EXPLAIN的key_len和Extra字段,光看key有值不够
模糊查询 LIKE 的位置决定能否用索引
LIKE 不是万能通配符,用法不对就彻底放弃索引。
- ✅
name LIKE '张%'—— 前缀匹配,可走索引 - ❌
name LIKE '%三'或name LIKE '%张%'—— 无法利用 B+ 树索引结构,全表扫描 - 如果业务真需要后缀搜索,考虑倒序存储 + 前缀匹配,或上全文索引(
FULLTEXT) - 注意类型隐式转换:
WHERE mobile = 13800138000(数字) vsWHERE mobile = '13800138000'(字符串),字段类型不一致会导致索引失效











