不加括号混用and/or会导致逻辑错误,如status = '已发货' and region = '华东' or region = '华南'实际等价于(status = '已发货' and region = '华东') or region = '华南',使所有华南地区订单被误查。

WHERE里混用AND/OR时括号漏了会出什么问题
不加括号的混合逻辑常导致结果错得离谱,而且很难一眼发现。MySQL按AND优先于OR解析,status = '已发货' AND region = '华东' OR region = '华南'实际等价于(status = '已发货' AND region = '华东') OR region = '华南'——所有华南地区的订单全被捞出来,不管状态是不是已发货。
- 只要出现
AND和OR共存,无条件加括号,哪怕只有一处 - 把语义相同的条件先归组:
(status = '已发货' OR status = '已签收')再跟其他条件AND - 用
IN替代多个OR:写status IN ('已发货', '已签收')既安全又易读
LIKE '%关键词'为什么查得慢,怎么改
LIKE开头带%(如name LIKE '%mini%')基本等于放弃索引,MySQL只能全表扫描。这不是配置问题,是B+树索引结构决定的——它只支持从左往右匹配前缀。
- 前缀匹配能走索引:
name LIKE 'iPhone%' - 后缀或中缀匹配没法优化,别硬扛:业务上拆字段(比如单独存品牌名、型号)、用全文索引(
FULLTEXT),或者引入Elasticsearch - 真要模糊查又必须用
LIKE,至少避免SELECT *,只查必要字段,减少IO
复合索引建了但EXPLAIN显示没用上,常见原因
EXPLAIN里key为空或rows接近总行数,说明索引白建了。最左前缀原则不是口号,是硬约束。
-
WHERE a = 1 AND c = 3对索引(a, b, c)只用到a,c跳过b直接失效 -
WHERE b = 2 AND c = 3整个索引完全不用——a缺失,最左就断了 - 在索引列上用了函数:
WHERE YEAR(created_at) = 2024→ 改成created_at BETWEEN '2024-01-01' AND '2024-12-31' - 范围查询后列不参与过滤:
WHERE a = 1 AND b > 10 AND c = 2中c不走索引查找(但若SELECT只查a,b,c,可能覆盖)
NULL值判断写=号会漏数据
NULL不是值,是“不存在”,所以phone = NULL永远为FALSE,查不到任何记录。这是新手掉坑最多的地方之一。
- 判空必须用
IS NULL或IS NOT NULL,不能用=、!=或 - 想把
NULL当默认值参与计算,用COALESCE(phone, '未知'),别写IFNULL或NULLIF除非真需要它们的语义 - 联合索引里含可空字段时要小心:
INDEX (region, status, phone)中如果phone IS NULL,这部分数据在索引里是特殊位置,WHERE region='华东' AND phone IS NULL能走索引,但WHERE phone IS NULL单独查就不行











