MySQL 5.7及以上版本中,WHERE 1=1不会影响性能,因其在查询优化阶段被常量折叠优化(Constant-Folding Optimization)自动移除,执行计划等同于无该条件的SQL。

MySQL 5.7 及以上版本中,WHERE 1=1 不会影响查询性能——它会被查询优化器在生成执行计划前彻底移除。
MySQL 查询优化器如何处理 1=1
MySQL 的查询优化器具备 Constant-Folding Optimization(常量折叠优化)能力,会在解析 SQL 阶段识别并消除恒真/恒假表达式。1=1 是典型的重言式(tautology),优化器不等执行就已将其剥离。
- 执行
EXPLAIN SELECT * FROM t_user WHERE 1=1 AND name = '张三';后,再运行SHOW WARNINGS;,能看到优化后的语句实际是SELECT ... FROM t_user WHERE (name = '张三') - 该优化发生在服务器层的“解析 → 重写 → 优化”阶段,与存储引擎无关,也不依赖索引是否存在
- 低版本(如 MySQL 5.6 及更早)理论上也可能优化,但未严格保证;生产环境若仍在用这类版本,建议升级或规避
WHERE 1=1
为什么有人测出性能差异?
所谓“差了 10 多倍”的案例,几乎都不是 1=1 本身导致的,而是它暴露或掩盖了其他问题:
-
1=1后拼接的条件写法不当,例如AND UPPER(name) = 'ZHANG'导致索引失效,误归因于1=1 - 动态 SQL 拼接逻辑有 bug,比如重复追加相同条件,或未清理空值参数,造成冗余谓词堆积
- 测试时未清空查询缓存(
query_cache_type=1已弃用,但旧环境仍可能存在干扰)或未用SQL_NO_CACHE控制变量 - 对比测试未控制变量:两次查询走的是不同执行计划(如一次命中缓存、一次触发隐式类型转换),而
1=1只是那条 SQL 的“占位符标签”
MyBatis 中 WHERE 1=1 vs <where> 标签
两者性能无实质差别,但行为逻辑和可维护性差异明显:
-
WHERE 1=1是纯 SQL 层技巧,完全依赖开发者手动拼接,<if>块漏写或条件为空时可能生成WHERE 1=1 AND这类语法错误(虽 MySQL 能容错,但语义不清) -
<where>是 MyBatis 框架层的语义化封装:仅当内部至少一个<if>有值时才输出WHERE关键字,并自动剔除开头多余的AND/OR - 框架生成的 SQL 更干净,
EXPLAIN看到的就是最终有效条件,调试和审计更直接
真正该警惕的不是 1=1,而是它的“存在感”
当一条 SQL 里出现 WHERE 1=1,它往往意味着:这是手拼的动态 SQL,且缺乏结构化约束。容易被忽略的点包括:
- 没做参数空值校验,
AND age = null被拼进去,结果查不到数据却无报错 - 没统一字段类型转换逻辑,字符串条件未加引号或数字条件被当字符串拼接
- 没考虑 SQL 注入风险,直接字符串拼接用户输入(哪怕用了
#{},若混用${}就危险)
这些才是拖慢性能、引发线上事故的根因——1=1 只是那个最显眼的“症状”。



















