where 1=1 是恒真占位符,用于简化动态sql条件拼接,避免判断首个条件;不采用 where true 是因部分数据库(如mysql 5.7)不支持布尔字面量,且1=1兼容性更广、解析更稳定。

WHERE 1=1 是什么,为什么不是 WHERE true
WHERE 1=1 是一个恒真条件,数据库执行时总会被优化掉,但它在拼接动态 SQL 时提供了一个安全的“起始占位符”。不用 WHERE true 是因为不是所有数据库都支持布尔字面量作为条件(比如 MySQL 5.7 默认不认 true 作表达式,SQL Server 要写 WHERE 1=1 或 WHERE (1=1) 才稳)。
它的核心价值不是逻辑功能,而是避免手动判断要不要加 WHERE 关键字——尤其在程序里用字符串拼接 SQL 时,每加一个条件都以 AND xxx 追加,就不会出现开头多出 AND 或漏写 WHERE 的语法错误。
拼接时怎么避免 SQL 注入和类型错误
直接拼接用户输入的值到 WHERE 1=1 AND name = 'xxx' 是高危操作。必须用参数化查询替代字符串拼接:
- Python + psycopg2:用
%s占位符,传参进cursor.execute(sql, params) - Java + JDBC:用
?占位符,配合PreparedStatement - Node.js + pg:用
$1,$2绑定参数
如果非要用字符串拼接(比如某些 ORM 不支持动态条件),至少对字段名做白名单校验,对值做转义或强制类型转换(例如 INT 类型字段只接受数字字符串,否则跳过该条件)。
NULL 值和空字符串容易导致条件失效
常见错误是写成:WHERE 1=1 AND status = :status,但当 :status 是 NULL 时,整条 AND 条件变成 UNKNOWN,结果被过滤掉——这不是你想要的“忽略该条件”。
正确做法是显式处理可选条件:
- 用
AND (:status IS NULL OR status = :status) - 或数据库特定写法,如 MySQL 可用
AND COALESCE(:status, status) = status(但可读性差) - 更清晰的写法是:只在
:status非空时才拼入AND status = ?,而不是全靠 SQL 层兜底
注意:空字符串 '' 和 NULL 在语义上不同,IS NULL 判不了 '',必要时要并列判断 :name IS NULL OR :name = '' OR name = :name。
WHERE 1=1 对执行计划有影响吗
现代数据库(PostgreSQL、MySQL 8+、SQL Server)都会在查询优化阶段直接剔除 1=1,不会影响执行计划或性能。你可以用 EXPLAIN 验证:两个语句(带/不带 WHERE 1=1)的执行计划完全一致。
但要注意两点:
- 别在视图或物化视图定义里硬写
WHERE 1=1——它没意义,还可能干扰后续查询重写 - 如果拼接逻辑混乱,导致生成了类似
WHERE 1=1 AND 1=1 AND ...的冗余条件,虽然不影响结果,但会增加解析开销(极少,但属于不良习惯)
真正影响性能的是后面那些未加索引的动态字段,比如 AND JSON_CONTAINS(metadata, ?) 或 AND UPPER(name) = UPPER(?) ——这些才是该盯住的地方。










