mysql 5.7+中where 1=1不影响性能,因其在解析→重写→优化阶段被常量折叠自动移除,explain与show warnings可验证优化后语句已剔除该条件,真正影响性能的是拼接逻辑缺陷如参数未校验、类型错位或null处理不当。

它本身不会影响查询性能——MySQL 5.7+ 会直接在解析阶段把 WHERE 1=1 常量折叠掉,执行计划里根本看不到它。
EXPLAIN 和 SHOW WARNINGS 能验证优化是否生效
运行 EXPLAIN SELECT * FROM user WHERE 1=1 AND name = 'tom' 后,再执行 SHOW WARNINGS,你会看到优化后的语句是 SELECT * FROM user WHERE (name = 'tom')。这说明 1=1 已被移除,不参与索引选择、不增加谓词计算、也不触发额外 I/O。
- 该优化发生在“解析 → 重写 → 优化”早期阶段,和存储引擎、索引是否存在都无关
- 仅对字面量恒真表达式有效,比如
1=1、'a'='a';而IF(1,1,0)=1或含用户变量的表达式可能逃逸优化 - 旧版本 MySQL(如 5.6 及更早)未完全实现常量折叠,但这类环境已基本退出主流生产场景
真正拖慢查询的是拼接逻辑本身,不是 1=1 这三个字符
你在 Navicat 里看到耗时波动或 type=ALL,大概率不是 1=1 的问题,而是它暴露出来的拼接缺陷:
- 参数未校验:比如
if (name != null)没覆盖空字符串,拼出AND name = ''导致全表扫 - 类型错位:数字字段拼成字符串(
"AND id = '" + userId + "'"),触发隐式转换,id索引失效 - NULL 处理不当:拼出
AND status = NULL,而= NULL永远返回 UNKNOWN,优化器放弃索引 - SQL 注入风险:直接字符串拼接且未用预编译,数据库不敢复用执行计划
MyBatis 场景下用 标签替代手写 WHERE 1=1
WHERE 1=1 是纯 SQL 层 hack,而 <where></where> 是框架层语义化处理:
-
<where></where>自动剔除无条件时的整个块,不会生成冗余WHERE - 所有
#{}占位符默认参数化,杜绝类型错配与注入入口 - 避免手拼时漏判空、重复追加、引号错位等低级但致命的问题
- 对比:
SELECT * FROM users WHERE 1=1 AND name = 'admin' AND status = 1(手拼,危险) vs 框架生成的干净 SQL
复杂点从来不在 1=1 本身,而在你是否意识到:它是一面镜子,照出的是参数校验有没有做、类型对齐有没有做、NULL 显式处理有没有做——这些细节在 Navicat 里一眼看不出,却能让执行计划彻底跑偏。










