【sql优化】where 1=1

文章目录

where 1=1

问题描述

在动态 SQL 拼接场景中,开发者常使用 WHERE 1=1 简化条件拼接逻辑(避免处理首个条件的 AND)。理论上,数据库优化器会忽略 1=1,但字符串拼接可能带来性能损耗,部分数据库优化器可能无法完全优化 1=1,导致索引失效或全表扫描。建议使用<where> 标签替代 WHERE 1=1 。

错误实现

sql 复制代码
select *
from job_info
where 1=1
<if test="jobName != null and jobName != '' ">
    <bind name="jobNameBind" value="'%' + jobName + '%'"/>
    and job_name like #{jobNameBind}
</if>

正确实现

sql 复制代码
select *
from job_info
<where>
<if test="jobName != null and jobName != '' ">
     <bind name="jobNameBind" value="'%' + jobName + '%'"/>
    job_name like #{jobNameBind}
</if>
</where>

性能对比测试

  • 数据库:mysql-8.0.29

  • EXPLAIN测试对比:

sql 复制代码
EXPLAIN SELECT * FROM koca_order WHERE 1=1 AND order_id > 1012

EXPLAIN SELECT * FROM koca_order WHERE order_id > 1012
id select_type type possible_keys rows filtered Extra
1 SIMPLE ALL PRIMARY 600 33.33 Using where
  • JMH测试:
java 复制代码
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(3)
@Warmup(iterations = 5, time = 2)
@Measurement(iterations = 5, time = 5)
@Threads(16)
public class WhereConditionBenchmark {

    private List<String> conditions;

    @Setup
    public void setup() {
        // 模拟 5 个动态查询条件
        conditions = Arrays.asList("age > 18", "status = 1", "name LIKE 'John%'", "city = 'NY'", "score >= 60");
    }

    /**
     * 原始实现:使用 WHERE 1=1 简化拼接
     */
    @Benchmark
    public void withDummyCondition(Blackhole bh) {
        StringBuilder sql = new StringBuilder("SELECT * FROM users WHERE 1=1");
        for (String cond : conditions) {
            sql.append(" AND ").append(cond);
        }
        bh.consume(sql.toString()); // 避免 JIT 优化
    }

    /**
     * 优化实现:直接拼接 WHERE 条件
     */
    @Benchmark
    public void withoutDummyCondition(Blackhole bh) {
        StringBuilder sql = new StringBuilder("SELECT * FROM users");
        boolean first = true;
        for (String cond : conditions) {
            if (first) {
                sql.append(" WHERE ");
                first = false;
            } else {
                sql.append(" AND ");
            }
            sql.append(cond);
        }
        bh.consume(sql.toString());
    }

}

测试结果:

plain 复制代码
Benchmark                                          Mode  Cnt      Score      Error   Units
TT.WhereConditionBenchmark.withDummyCondition     thrpt   15  16509.986 ± 3028.386  ops/ms
TT.WhereConditionBenchmark.withoutDummyCondition  thrpt   15  20124.583 ±  420.773  ops/ms

测试结论:

移除冗余的 WHERE 1=1 后,吞吐量提升约 21.9%,说明 1=1 对动态 SQL 生成性能有明显影响。

相关推荐
xuekai200809011 分钟前
GaussDB-SQL优化案例
数据库·sql·gaussdb
老邓计算机毕设3 分钟前
SSM养老院管理系统的设计于实现78fyn(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·计算机毕业设计·养老院管理系统·ssm 框架
a程序小傲5 分钟前
京东Java面试被问:基于Gossip协议的最终一致性实现和收敛时间
java·开发语言·前端·数据库·python·面试·状态模式
重生之绝世牛码8 分钟前
Linux软件安装 —— PostgreSQL集群安装(主从复制集群)
大数据·linux·运维·数据库·postgresql·软件安装·postgresql主从集群
程序员小白条12 分钟前
面试 Java 基础八股文十问十答第二十二期
java·开发语言·数据库·面试·职场和发展·毕设
万象.19 分钟前
redis客户端安装与实现C++版本
数据库·c++·redis
Yiyaoshujuku27 分钟前
疾病的发病率、发病人数、患病率、患病人数、死亡率、死亡人数查询网站及数据库
数据库·人工智能·算法
不想写bug呀28 分钟前
Redis总结
数据库·redis·缓存
Neolnfra40 分钟前
数据库提权实战指南
数据库·数据库安全
DarkAthena1 小时前
【GaussDB】合入原生PG的PR来修复CVE-2025-1094漏洞后产生的严重隐患
数据库·漏洞·gaussdb