WHERE 子句里多个条件用 AND 还是 OR?看逻辑关系
WHERE子句本身不决定用哪个逻辑运算符,关键是你想表达的业务含义。
AND表示所有条件都必须为真,
OR表示只要一个为真就匹配。 查询年龄在 25 到 35 之间且城市是“北京”的用户:
SELECT * FROM users WHERE age >= 25 AND age <= 35 AND city = '北京';查询是管理员或者状态为激活的用户:
SELECT * FROM users WHERE role = 'admin' OR status = 'active';混用时注意优先级:
AND优先级高于
OR,没加括号容易出错。比如
role = 'admin' OR status = 'active' AND deleted = 0实际等价于
role = 'admin' OR (status = 'active' AND deleted = 0),不是你想查的“(管理员或激活)且未删除”。
NULL 值在 WHERE 条件中不能用 = 判断
MySQL 中
NULL不等于任何值,包括它自己。写
WHERE column = NULL永远不返回结果。 正确写法是用
IS NULL或
IS NOT NULL:
SELECT * FROM orders WHERE shipped_at IS NULL;如果要同时匹配非空值和
NULL,不能写成
WHERE status = 'shipped' OR status = NULL,得拆开:
SELECT * FROM orders WHERE status = 'shipped' OR status IS NULL;使用
COALESCE()或
IFNULL()可以临时把
NULL转成具体值再比较,但要注意索引失效风险。
LIKE 模糊查询带 % 开头会导致索引失效
LIKE是常用多条件筛选手段,但性能差异极大:
name LIKE '张%':能走
name字段上的 B+ 树索引
name LIKE '%三'或
name LIKE '%王%':无法使用索引,全表扫描 中文场景下还容易遇到字符集问题:确保字段和连接的
collation支持中文,比如
utf8mb4_unicode_ci;否则
LIKE '李%'可能漏掉某些拼音变体 替代方案:全文索引(
FULLTEXT)适合大文本搜索,但只支持
MyISAM和
InnoDB(5.6+),且对短词效果差
IN 列表超过 1000 项可能触发性能或语法限制
IN看似简洁,但实际使用有隐性边界: MySQL 默认没有硬性上限,但过长的
IN列表会显著增加 SQL 解析时间和执行计划复杂度 某些中间件(如 ShardingSphere、MaxCompute JDBC 驱动)会主动截断或报错,常见阈值是 1000 项 替代做法: 把 ID 列表写入临时表,改用
JOIN或子查询 分批查询,比如每次 500 个 ID,循环执行 用
WHERE id BETWEEN ? AND ?配合有序主键,效率更高 注意
IN (NULL, 1, 2)的行为:如果字段本身允许
NULL,这个条件不会匹配
NULL行,因为
NULL IN (NULL, 1, 2)返回
UNKNOWN,不是
TRUE
实际写多条件
WHERE时,最容易被忽略的是运算符优先级、
NULL的三值逻辑,以及看似无害的
LIKE '%xxx'对查询性能的毁灭性影响。
