李锋镝的博客

  • 首页
  • 时间轴
  • 说说
  • 左邻右舍
  • 博友圈
  • 关于我
    • 关于我
    • 另一个网站
    • 我的导航站
    • 网站地图
    • 赞助
  • 留言
  • 走心评论
  • 系列文章
  • Now
  • 每日心情
  • 🚇开往
Destiny
自是人生长恨水长东
  1. 首页
  2. 中间件
  3. 正文

在 SQL 中做范围查询时,使用 BETWEEN AND 和直接用 >/=/<= 这类比较运算符,哪一个的性能更优。

2026年1月15日 约 1,091 字4 分钟 6点热度 0人点赞 0条评论
本文最后更新于 2026年1月15日,距今已 192 天,其中的信息可能已经发生变化,请注意甄别。

核心结论先明确:在绝大多数数据库(MySQL/Oracle/PostgreSQL等)中,二者的性能几乎完全一致,因为数据库优化器会将 BETWEEN AND 自动等价转换为 >= + <= 的组合。性能差异的关键不在运算符本身,而在「是否能利用索引」「范围边界的合理性」。

一、底层逻辑:BETWEEN AND 是语法糖

BETWEEN AND 本质是数据库提供的「语法简化工具」,而非特殊的执行逻辑。

  • 例如:age BETWEEN 18 AND 30
    优化器会自动解析为:age >= 18 AND age <= 30
  • 例如:create_time BETWEEN '2026-01-01' AND '2026-01-15'
    等价于:create_time >= '2026-01-01' AND create_time <= '2026-01-15'

数据库执行计划(EXPLAIN)会显示二者的执行逻辑完全相同:

  • 有索引时:均走「索引范围扫描(RANGE SCAN)」;
  • 无索引时:均走「全表扫描(TABLE SCAN)」。

二、唯一可能的性能差异:边界值处理(非性能本身,是逻辑)

虽然性能无差异,但需注意 BETWEEN AND 的「闭区间特性」可能间接影响结果集大小,进而看似“性能不同”:

写法 逻辑等价 结果集特点 适用场景
age BETWEEN 18 AND 30 age >=18 AND age <=30 包含18和30(闭区间) 明确需要包含边界值
age >18 AND age <30 无等价简化 排除18和30(开区间) 明确需要排除边界值

示例(MySQL实操):
假设有 user 表(100万行,age 列有B-tree索引),执行计划完全一致:

-- 写法1:BETWEEN AND
EXPLAIN SELECT * FROM user WHERE age BETWEEN 18 AND 30;
-- 执行计划:type=range,key=age(走age索引,范围扫描)

-- 写法2:>= + <=
EXPLAIN SELECT * FROM user WHERE age >= 18 AND age <= 30;
-- 执行计划:和上面完全一致,rows/Extra等字段无差异

-- 写法3:> + <(逻辑不同,结果集更小,但执行方式仍一致)
EXPLAIN SELECT * FROM user WHERE age > 18 AND age < 30;
-- 执行计划:仍走age索引,仅扫描范围缩小为(18,30)

三、影响性能的核心因素(与运算符无关)

真正决定范围查询性能的是以下几点,而非用 BETWEEN AND 还是 >/<:

  1. 索引是否生效

    • 有B-tree索引(数值/日期/字符串列):范围查询性能极优(仅扫描索引范围内的数据);
    • 无索引/索引失效(如列加了函数、用了不等于/OR等):全表扫描,性能差(和运算符无关)。
  2. 范围大小

    • 小范围(如查1天的数据):即使全表扫描也快;
    • 大范围(如查1年的数据):必须依赖索引,否则性能极差。
  3. 数据库版本/优化器

    • 老旧数据库(如MySQL 5.5及更早)对复杂范围的解析略慢,但 BETWEEN AND 和 >=/<= 仍无差异;
    • 新版本数据库(MySQL 8.0/Oracle 19c)优化器更智能,二者执行效率完全对齐。

四、使用建议(性能+可读性兼顾)

  1. 优先用 BETWEEN AND:

    • 场景:需要「闭区间」范围查询(包含边界值);
    • 优势:代码更简洁,可读性更高(比如 time BETWEEN '2026-01-01' AND '2026-01-15' 比 time >= ... AND time <= ... 更易读)。
  2. 用 >/< 组合:

    • 场景:需要「开区间」范围查询(排除边界值);
    • 注意:避免写成 age > 18 AND age < 30 替代 BETWEEN 19 AND 29(逻辑等价但可读性差)。
  3. 避坑点:

    • 日期范围查询时,BETWEEN '2026-01-01' AND '2026-01-31' 等价于 <= '2026-01-31 00:00:00',会漏掉31日的所有时间数据,此时必须用 <= '2026-01-31 23:59:59' 或 <'2026-02-01',这是逻辑问题而非性能问题。

总结

  1. 性能层面:BETWEEN AND 和 >=/<= 组合完全等价,无性能差异;
  2. 逻辑层面:BETWEEN AND 是闭区间,>/< 可灵活控制开/闭区间;
  3. 核心优化:范围查询性能的关键是「列是否有有效索引」,而非运算符选择。

简单来说:按业务逻辑选择写法(闭区间用 BETWEEN AND,开区间用 >/<),无需纠结性能,重点保证索引生效即可。

除非注明,否则均为李锋镝的博客原创文章,转载必须以链接形式标明本文链接

本文链接:https://www.lifengdi.com/zhong-jian-jian/4677

推荐阅读

  • 千万级大表新增字段实战指南:告别锁表与业务中断
  • 深入了解PostgreSQL
  • 分库分表正在被淘汰?NewSQL与分库分表的深度博弈与选型指南
  • 数据库事务的隔离级别
  • 数据库事务的一点简单总结
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: SQL 数据库
最后更新:2026年1月15日

岁月同一天 7 月 27 日

回望过去的今天,你在写什么

  • 6 年前 2020年7月27日
    JVM详细参数说明

    JVM内存结构 由上图可以清楚的看到JVM的内存空间分为3大部分: 堆内存 方法区 栈内存 其中栈内存可以再细分为jav…

相关文章
  • Java中PO、VO、BO、DTO、POJO、DAO释义2019年6月28日
  • 使用AbstractRoutingDataSource动态切换数据源2025年3月15日
  • Spring Boot 2.x使用PostgreSQL数据库2021年10月9日
  • 数据库中的锁-SQL Server版2019年10月9日
  • MySQL数据库查看执行计划以及名词解释2019年9月12日

李锋镝

既然选择了远方,便只顾风雨兼程。

打赏 点赞
< 上一篇
下一篇 >
1234567891112131415161718192021222324252627282930313233343536373839404142434446474849505152535455575859606162636465666769727476777879808182858687909293949596979899
取消回复
…

文章评论

还没有评论,快来抢沙发吧~

娉娉袅袅十三余,豆蔻梢头二月初。
春风十里扬州路,卷上珠帘总不如。

听点儿音乐吧 朋友~
文章目录
最新 热点 随机
最新 热点 随机
给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能 增加了两套复古皮肤-牛皮纸、千禧网页 Claude Design介绍与使用 Kratos+主题新功能介绍 Taste Skill 说明与使用 jasypt-spring-boot 使用说明
AI时代,个人技术博客的出路在哪里?给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能这个域名注册整整十年了,十年时间,真快啊WordPress实现用户评论等级排行榜插件WordPress网站换了个字体,差点儿把样式换崩了做了一个WordPress文章热力图插件
Linux开启FTP 这个域名注册整整十年了,十年时间,真快啊 探讨全球多站点跨机房数据传输场景下QUIC协议的优劣 《人生海海》读后感 Kafka 为什么要抛弃 Zookeeper? Tomcat7.0配置CORS(跨域资源共享)
最近评论
李锋镝 发布于 3 天前(07月24日) 牛皮纸自带经典款老钱风buff~
满心 发布于 3 天前(07月24日) 牛皮纸还是好看
李锋镝 发布于 4 天前(07月23日) 都是AI的功劳~ :21:
林羽凡 发布于 4 天前(07月23日) 好久没来了,果然大佬就是大佬,太厉害了,博客的时间轴不错呀。
李锋镝 发布于 4 天前(07月23日) 布局确实有点儿像,哈哈哈
标签聚合
多线程 分布式 AI K8s 架构 IDEA MySQL docker ElasticSearch SQL Spring AI编程 Redis JAVA JVM WordPress 数据库 SpringBoot 日常 设计模式
友情链接
  • 知向前端
  • 瓦匠个人小站
  • 皮皮社
  • Mr.Sun的博客
  • 韩情脉脉
  • 旧时繁华
  • 风渡言
  • 懋和道人
  • 搬砖日记
  • 临窗旋墨
  • Blogs·CN
  • 老张博客
  • 哥斯拉
  • 林羽凡
  • 韩小韩博客
  • 彬红茶日记
  • Honesty
  • 拾趣博客导航
  • 志文工作室

COPYRIGHT © 2026 lifengdi.com. ALL RIGHTS RESERVED.

域名年龄

Theme Kratos+ By Dylan Li

津ICP备2024022503号-3

京公网安备11011502039375号