一、WHERE 1=1 是干嘛的
一句话:纯粹为了方便拼接 SQL,没有任何逻辑意义。
最常见的使用场景:动态 SQL
java
// 后端动态拼接查询条件
String sql = "SELECT * FROM user WHERE 1=1";
if (name != null) {
sql += " AND name = '" + name + "'";
}
if (age != null) {
sql += " AND age = " + age;
}
生成的 SQL 可能是:
sql
-- name 和 age 都传了
SELECT * FROM user WHERE 1=1 AND name = '张三' AND age = 25;
-- 只传了 name
SELECT * FROM user WHERE 1=1 AND name = '张三';
-- 什么都没传
SELECT * FROM user WHERE 1=1;
好处:
- 不用判断"是不是第一个条件"来决定加
WHERE还是AND - 动态拼接时代码简洁,不用处理首条件前缀问题
那 WHERE 1=1 本身对性能有影响吗?
几乎没有。 优化器会直接把它当成恒真条件消掉:
sql
-- 优化器眼里,这两条完全等价:
SELECT * FROM user WHERE 1=1 AND name = '张三';
SELECT * FROM user WHERE name = '张三';
MySQL / PostgreSQL / Oracle 的优化器都会做 常量折叠(Constant Folding) ,把 1=1 直接去掉,执行计划一模一样。
二、用的是什么索引?
1=1 本身不用任何索引。
它只是一个恒为 TRUE 的布尔表达式 ,优化器直接忽略它。真正决定走不走索引、走哪个索引的,是 AND 后面的有效条件:
sql
-- 决定索引的是 name = '张三',不是 1=1
SELECT * FROM user WHERE 1=1 AND name = '张三';
| 条件 | 是否用索引 | 原因 |
|---|---|---|
1=1 |
❌ 不用 | 恒真,被优化器直接消除 |
name = '张三' |
✅ 看情况 | name 列有索引就可能走,没有就全表扫描 |
1=0 |
❌ 不用 | 恒假,优化器直接返回空结果集,连表都不扫 |
三、顺便提几个相关的"奇怪写法"
1. WHERE 1=0 → 快速拿表结构,不返回数据
sql
SELECT * FROM user WHERE 1=0;
优化器直接判定结果为空,连表都不打开,常用于:
- 只想要字段结构(比如 BI 工具探测表结构)
- 创建空表:
CREATE TABLE t2 AS SELECT * FROM t1 WHERE 1=0;
2. WHERE 1 → 和 WHERE 1=1 等价
有些老代码写 WHERE 1,效果完全一样,都是恒真。
3. 动态 SQL 的现代写法(推荐)
现在用 MyBatis 等框架,不需要手写 1=1 了:
xml
<select id="query" resultType="User">
SELECT * FROM user
<where>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
<where> 标签会自动处理:
- 如果里面没有条件,不生成
WHERE关键字 - 自动去掉第一个条件前的
AND/OR
四、一句话总结
WHERE 1=1是给程序员用的,不是给数据库用的。 它不参与索引选择,不影响执行计划,优化器直接把它当空气。真正决定性能和索引的是后面那些有意义的条件。