IN和BETWEEN在索引效能的区别

1. 核心区别:等值遍历 vs. 连续扫描

IN:视为多个等值点(Point Search)

当你使用 IN (1, 2, 3) 时,MySQL 优化器通常会将其处理为:

  • 先去找 1 的位置,再去找 2 的位置,最后去找 3 的位置。
  • 关键点 :在联合索引 (a, b) 中,如果 a 使用了 IN,因为 a 的每一个值都是确定的,MySQL 可以继续利用索引的有序性去过滤 b。
>, <, BETWEEN:视为线段扫描(Range Scan)

当你使用 a > 10 时,MySQL 认为 a 是一个连续的区间。

  • 关键点 :虽然 a 是有序的,但在 a > 10 这个大区间内,b 是无序 的(只有在 a 相等的情况下 b 才有序)。
  • 结果 :索引的效能在 a 字段就停止了,后续的 b 字段无法利用索引进行快速定位。

2. 实验对比

假设索引为 (age, score):

场景 A:使用 IN
sql 复制代码
SELECT * FROM users WHERE age IN (20, 30) AND score > 80;
  • MySQL 的动作 :
    1. 去索引树找 age=20 的位置,并在该范围内利用索引寻找 score > 80。
    2. 再去找 age=30 的位置,并在该范围内利用索引寻找 score > 80。
  • 结论 :age 和 score 两个字段都用到了索引。
场景 B:使用 BETWEEN 或 >
sql 复制代码
SELECT * FROM users WHERE age BETWEEN 20 AND 30 AND score > 80;
  • MySQL 的动作 :
    1. 找到 age=20 的起始位置,开始往后扫描,直到 age=30。
    2. 在扫描过程中,它无法通过索引"跳跃"找到 score > 80 的记录,只能一条条检查 score 是否符合要求。
  • 结论 :只有 age 用到了索引,score 索引失效。

3. 性能层面的区别

特性 IN (val1, val2) >, <, BETWEEN
底层分类 多个等值查询 (Multiple Equalities) 范围查询 (Range)
索引连续性 不截断后续索引字段 截断后续索引字段
排序 (Order By) 可能导致索引排序失效(需看具体执行计划) 必然导致后续字段排序失效
优化器开销 列表值越多,计算索引成本的开销越大 成本计算简单

4. 特殊情况:MySQL 8.0 的"跳跃扫描" (Skip Scan)

在 MySQL 8.0+ 中,如果联合索引的前缀列区分度很低(比如只有几个枚举值),即使你用了范围查询,优化器有时也会尝试通过"跳跃扫描"来强行利用后面的索引字段。但这种优化是不稳定的,最稳健的方法依然是把范围查询放在索引的最后。


5. 什么时候 IN 也会变成"范围条件"?

虽然 IN 表现得像等值,但如果 IN 列表中的值过多 (超过了 eq_range_index_dive_limit 配置的值),或者它是通过一个复杂的子查询产生的,MySQL 可能会放弃点对点查找,将其降级为范围扫描。此时,它对后续索引列的影响就和 BETWEEN 一样了。

相关推荐
换元不配限2 小时前
从 AsyncTask 到现代并发:Android 异步方案的演进与替代实践
android·asynctask·异步编程·方案对比·asynctask替代方案
用户2018792831672 小时前
你的 App 为什么是「电量刺客」?——从一条 WakeLock 追到 Linux 内核的 Android 省电原理全解
android
mmsx2 小时前
Android 安全校验下沉到原生层:防 patch 与构建期自动化
android·安全·自动化
2501_915909063 小时前
抓包工具断点拦截是什么?如何半路拦截修改 HTTP 请求
网络协议·计算机网络·网络安全·adb·https·udp
老牛日常随笔3 小时前
Google把Android测试搬进AI对话:ARTEMIS如何用自然语言操作你的手机
android·人工智能·智能手机
朱涛的自习室4 小时前
预算 1000 美金的开源软件,DeepSeek 只花 1 美金就做完了(Day 6)
android·前端·人工智能
mmsx5 小时前
Android APK 加固方案怎么落地:从加壳到校验的组合取舍
android·网络·安全·签名
hunterandroid5 小时前
Navigation Component 工程落地:从单 Activity 架构到深度链接配置
android·前端
撩得Android一次心动5 小时前
Jetpack Compose 知识点整理3【个人用】
android·笔记·学习·kotlin·android compose