SQL中为什么不要使用1=1
最近看几个老项目的SQL条件中使用了1=1,想想自己也曾经这样写过,略有感触,特别拿出来说道说道。
编写SQL语句就像炒菜,每一种调料的使用都可能会影响菜品的最终味道,每一个SQL条件的加入也可能会影响查询的执行效率。那么 1=1 存在什么样的问题呢?为什么又会使用呢?
为什么会使用 1=1?
在动态构建SQL查询时,查询条件往往都是动态的,最终执行时可能会使用不同的条件。这时候,他们就会使用“1=1”作为一个始终为真的条件,让接下来的所有条件都可以方便地用“AND”连接起来,就像是搭积木的时候先放一个基座,其他的积木块就都可以在这个基座上叠加。
就像下边这样:
SELECT * FROM table WHERE 1=1
<if test="username != null">AND username = #{username}
</if>
<if test="age > 0">AND age = #{age}
</if>
这样就不用在增加每个条件之前先判断是否需要添加“AND”。
1=1 带来的问题
性能问题?
我们先来了解一下数据库查询优化器的工作原理。查询优化器就像是一个聪明的图书管理员,它知道如何最快地找到你需要的书籍。当你告诉它所需书籍的特征时,它会根据这些信息选择最快的检索路径。比如你要查询作者是“谭浩强”的书籍,它就选择先通过作者索引找到书籍索引,再通过书籍索引找到对应的书籍,而不是费力的把所有的书籍遍历一遍。
但是,如果我们告诉它一些无关紧要的信息,比如“我要一本书,它是一本书”,这并不会帮助管理员更快地找到书,反而可能会让他觉得困惑。一个带有“1=1”的查询可能会让数据库去检查每一条记录是否满足这个始终为真的条件,这就像是图书管理员不得不检查每一本书来确认它们都是书一样,显然是一种浪费。
你可能会说:数据库没有这么傻吧?
确实,这实际上可能不会产生问题,因为现代数据库的查询优化器已经非常智能,它们通常能够识别出像 1=1 这样的恒真条件,并在执行查询计划时优化掉它们。在许多情况下,即使查询中包含了1=1,数据库的性能也不会受到太大影响,优化器会在实际执行查询时将其忽略。
但是优化器并不是万能的。在某些复杂的查询场景中,即使是简单的 1=1 也可能对优化器的决策造成不必要的影响,比如导致全表扫描。
代码质量
另外从代码质量的角度,我们也需要避免在查询中包含 1=1,有以下几点考虑:
- 代码清晰性:即使数据库可以优化掉这样的条件,但对于阅读SQL代码的人来说,1=1可能会造成困惑。代码的可读性和清晰性非常重要,特别是在团队协作的环境中。
- 习惯养成:即使在当前的数据库系统中1=1不会带来性能问题,习惯了写不必要的代码可能会在其他情况下引入实际的性能问题。比如,更复杂的无用条件可能不会那么容易被优化掉。
- 跨数据库兼容性:不同的数据库管理系统(DBMS)可能有不同的优化器能力。一个系统可能轻松优化掉1=1,而另一个系统则可能不那么高效。编写不依赖于特定优化器行为的SQL语句是一个好习惯。
编写尽可能高效、清晰和准确的SQL语句,不仅有助于保持代码的质量,也让代码具有更好的可维护性和可扩展性。
替代 1=1 的更佳做法
现在开发者普遍使用ORM框架来操作数据库了,还在完全手写拼SQL的同学可能需要反思下了,这里给两个不同ORM框架下替代1=1的方法。
假设我们有一个用户信息表 user,并希望根据传入的参数动态地过滤用户。
首先是Mybatis:
<!-- MyBatis映射文件片段 -->
<select id="selectUsersByConditions" parameterType="map" resultType="com.example.User">SELECT * FROM user<where><!-- 使用if标签动态添加条件 --><if test="username != null and username != ''">AND username = #{username}</if><if test="age > 0">AND age = #{age}</if><!-- 更多条件... --></where>
</select>
在 MyBatis 中,避免使用 1=1 的典型方法是利用动态SQL标签(如 <if>
)来构建条件查询。<where>
标签会自动处理首条条件前的 AND 或 OR。当没有满足条件的 <if>
或其他条件标签时,<where>
标签内部的所有内容都会被忽略,从而不会生成多余的 AND 或 WHERE 子句。
再看看 Entity Framework 的方法:
var query = context.User.AsQueryable();
if (!string.IsNullOrEmpty(username))
{query = query.Where(b => b.UserName.Contains(username));
}
if (age>0)
{query = query.Where(b => b.Age = age);
}
var users = query.ToList();
这是一种函数式编程的写法,最终生成SQL时,框架会决定是否在条件前增加AND,而不需要人为的增加 1=1。
总结
“1=1”在SQL语句中可能看起来无害,但实际上它是一种不良的编程习惯,可能会导致性能下降。就像在做饭时不会无缘无故地多加调料一样,我们在编写SQL语句时也应该避免添加无意义的条件。
每一行代码都应该有它存在的理由,不要让人和数据库浪费时间在不必要的事情上。
相关文章:
SQL中为什么不要使用1=1
最近看几个老项目的SQL条件中使用了11,想想自己也曾经这样写过,略有感触,特别拿出来说道说道。 编写SQL语句就像炒菜,每一种调料的使用都可能会影响菜品的最终味道,每一个SQL条件的加入也可能会影响查询的执行效率。那…...
python 几种常见的音频数据读取、保存方式
1. soundfile 库的使用 soundfile库是一个Python库,主要用于读取和写入音频文件。它支持多种音频格式,包括WAV、AIFF、FLAC和OGG等。通过soundfile库,用户可以方便地将numpy数组存储到音频文件或者将音频文件加载到numpy数组中。此外&#x…...

关于msvcr120.dll丢失怎样修复的详细解决步骤方法分享,msvcr120.dll文件的相关内容
在电脑使用过程中,我们经常遇到各种系统错误,其中msvcr120.dll丢失是一个常见问题。msvcr120.dll文件是Visual C Redistributable for Visual Studio 2015/2017的一个组件,主要用于支持某些应用程序的正常运行。当电脑出现msvcr120.dll丢失情…...

简单几步通过DD工具把云服务器系统Linux改为windows
简单几部通过DD安装其他系统,当服务器的web控制台没有我们要装的系统,就需要通过DD(Linux磁盘)工具来更改系统,(已知支持KVM系统) 本文如何简单的更换系统,不通过web控制台来更换&a…...

使用 package.json 配置代理解决 React 项目中的跨域请求问题
使用 package.json 配置代理解决 React 项目中的跨域请求问题 当我们在开发前端应用时,经常会遇到跨域请求的问题。为了解决这个问题,我们可以通过配置代理来实现在开发环境中向后端服务器发送请求。 在 React 项目中,我们可以使用 package…...
生成 Let‘s Encrypt 免费证书
文章目录 1. 安装 acme.sh2. 添加云服务商安全访问密钥并授权管理DNS记录3. 当前 Shell 添加安全访问密钥变量4. 生成证书5. 拷贝证书6. 清理安全访问密钥变量7. 打开脚本自动更新 代码仓库地址:https://github.com/Neilpang/acme.sh 1. 安装 acme.sh yum -y insta…...
int128的实现(基本完成)
虽然有一个声明叫_int128但是这并不是C标准: long long 不够用?详解 __int128 - FReQuenter - 博客园 (cnblogs.com) 网络上去找int128的另类实现方法,发现几乎都是在介绍_int128的 然后我就自己想了个办法,当时还没学C…...
【linux】使用 acme.sh 实现了 acme 协议生成免费的SSL 证书
acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书. 主要步骤: 安装 acme.sh生成证书copy 证书到 nginx/apache 或者其他服务更新证书更新 acme.sh出错怎么办, 如何调试 下面详细介绍. 1. 安装 acme.sh 安装很简单, 一个命令: curl https://get.acme.sh | sh…...
MACOS上面C/C++获取网卡索引,索引获取网卡接口名
依赖函数: if_nametoindex IF名字 to IF索引 if_indextoname IF索引 to IF名字 MACOS 10.7 版本支援(就是2011年发不OSX的第一个面向用的系统版本) int GetInterfaceIndex(const ppp::string& ifrName) noexcept{if (ifrName.empt…...

解决SSH远程登录开饭板出现密码错误问题
输入“adduser Zhanggong回车”,使用adduser命令创建开发板用户名为Zhanggong 输入密码“123456” 输入密码“123456”...
什么时候用ref和reactive
在Vue 3中,ref和reactive都是用于创建响应式数据的工具,但它们的使用场景有所不同。 使用ref的情况: 基本数据类型:当你需要响应式地处理基本数据类型(如数字、字符串、布尔值)时,应该使用ref…...
Java实战:Spring Boot实现邮件发送服务
本文将详细介绍如何在Spring Boot应用程序中实现邮件发送服务。我们将探讨Spring Boot集成邮件发送服务的基本概念,以及如何使用Spring Boot和第三方邮件服务提供商来实现邮件发送。此外,我们将通过具体的示例来展示如何在Spring Boot中配置和使用邮件发…...
重磅!MongoDB推出Atlas Stream Processing公共预览版
日前,MongoDB宣布推出Atlas Stream Processing公共预览版。 在Atlas平台上有兴趣尝试这项功能的开发者都享有完全的访问权限,可前往“阅读原文”链接点击了解更多详细信息或立即开始使用。 开发者喜欢文档型数据库的灵活性、易用性以及Query API查询方…...

dell戴尔电脑灵越系列Inspiron 15 3520原厂Win11系统中文版/英文版
Dell戴尔笔记本灵越3520原装出厂Windows11系统包,恢复出厂开箱预装OEM系统 链接:https://pan.baidu.com/s/1mMOAnvXz5NCDO_KImHR5gQ?pwd3nvw 提取码:3nvw 原厂系统自带所有驱动、出厂主题壁纸、系统属性联机支持标志、Office办公软件、MyD…...

k8s(3)
目录 一.K8S的三种网络 flannel的三种模式: 在 node01 节点上操作: calico的 三种模式: flannel 与 calico 的区别? 二.CoreDNS 在所有 node 节点上操作: 在 master01 节点上操作: 编辑 DNS 解析测试&#…...

Java多线程并发学习
一、Java 中用到的线程调度 1. 抢占式调度: 抢占式调度指的是每条线程执行的时间、线程的切换都由系统控制,系统控制指的是在系统某种运行机制下,可能每条线程都分同样的执行时间片,也可能是某些线程执行的时间片较长࿰…...

Curfew e-Pass 管理系统存在Sql注入漏洞 附源代码
免责声明:本文所涉及的信息安全技术知识仅供参考和学习之用,并不构成任何明示或暗示的保证。读者在使用本文提供的信息时,应自行判断其适用性,并承担由此产生的一切风险和责任。本文作者对于读者基于本文内容所做出的任何行为或决…...

记阿里云mysql丢表丢数据的实践记录
第一时间挂工单,联系工程师指引,现在回过来想,第一时间要确认发生时间。 1.通过性能视图(马后炮的总结,实际凭记忆恢复了三四次才找到数据) 2.先恢复数据 通过Navicat工具,结构同步࿰…...
自然语言转SQL的应用场景探索
自然语言转SQL的应用场景探索 1. 自然语言转sql有哪些解决方案2. 自然语言转sql有哪些应用场景3. 自然语言转sql在智能制造领域有哪些应用场景 1. 自然语言转sql有哪些解决方案 自然语言转SQL(NL2SQL)是一个涉及自然语言处理(NLP)…...
Python学习笔记——PySide6设计GUI应用之UI与逻辑分离
1、打开PySide6的UI设计工具pyside6-designer,设计一个主窗口,保存文件名为testwindow.ui 2、使用PySide6的RCC工具把testwindow.ui文件转换为testwindow_rc.py文件,此文件中有一个类Ui_MainWindow(包含各种控件对象)…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
前端中slice和splic的区别
1. slice slice 用于从数组中提取一部分元素,返回一个新的数组。 特点: 不修改原数组:slice 不会改变原数组,而是返回一个新的数组。提取数组的部分:slice 会根据指定的开始索引和结束索引提取数组的一部分。不包含…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...