当前位置: 首页 > news >正文

建立了 abc 联合索引,where a = ? and b = ? order by c 能命中索引吗?

解答这个问题之前我的建议是自己写个代码测试一下,在面试被问到的时候 回答更有底气。

-- 想象中的表结构
CREATE TABLE orders (user_id     INT,        -- 用户IDshop_id     INT,        -- 店铺ID  order_time  DATETIME,   -- 下单时间amount      DECIMAL(10,2)
);-- 创建联合索引:(user_id, shop_id, order_time)
CREATE INDEX idx_user_shop_time ON orders (user_id, shop_id, order_time);

所以先创建一个表,并且创建联合索引

如果查询有a、b、c并且按照顺序

explain SELECT * FROM orders
WHERE user_id = 1001 AND shop_id = 2005
ORDER BY order_time;

可以看到是走了索引的。

如果查询只有b和c

explain SELECT * FROM orders
WHERE shop_id = 2005 AND order_time = '2025-01-01 10:00:00';

显而易见,如果没有遵循最左匹配 那么索引会失效 不会走索引

a、b、c都有 但是顺序是乱的

SELECT * FROM orders
WHERE order_time = '2025-01-01 10:00:00'AND user_id = 1001AND shop_id = 2005;

能看出查询顺序是c、a、b

但还是走了索引,这是为什么呢 不是并没有满足最左前缀匹配吗

  1. MySQL 查询优化器(Optimizer)会重写查询条件的顺序

    • 它知道索引是 (user_id, shop_id, order_time)
    • 它会自动将等值条件按索引顺序排列:先 user_id=1001,再 shop_id=2005,最后 order_time=...
    • 所以实际执行时,等价于:
      WHERE user_id = 1001 AND shop_id = 2005 AND order_time = '2025-01-01 10:00:00'
  2. 满足最左前缀原则

    • user_id 是等值条件,命中索引第一列 ✅
    • shop_id 是等值条件,命中第二列 ✅
    • order_time 是等值条件,命中第三列 ✅
    • 所有字段都在索引中,可以快速定位唯一一行(或少数几行)
  3. 结果:高效走索引,使用 refconst 类型访问,无需全表扫描

只有a、b

explain SELECT * FROM orders
WHERE user_id = 1001AND shop_id = 2005;

也是走了索引的,并且效率更高

原因分析:
  • 索引是 (user_id, shop_id, order_time)
  • 查询条件使用了前两个字段:user_id=? 和 shop_id=?
  • 完全符合最左前缀原则(Leftmost Prefix)
  • 数据库可以:
    1. 快速定位到 user_id=1001 的所有记录
    2. 在这些记录中,再快速筛选出 shop_id=2005 的子集
    3. 找到后直接回表获取 amount 等字段

只有a、c

explain SELECT * FROM orders
WHERE user_id = 1001AND order_time = '2025-01-01 10:00:00';

虽然使用了联合索引,但只在 a 字段上进行了高效定位,而 c 字段的条件无法直接通过索引定位(因为跳过了中间的 b 字段),因此数据库需要对 a=... 对应的索引范围进行扫描,并逐行过滤 c 的值,无法完全利用索引的有序性

原因分析:
  • 索引顺序是:user_id → shop_id → order_time
  • 查询条件是:user_id=? 和 order_time=?
  • 虽然 user_id 是最左字段,可以使用 ✅
  • 但跳过了中间的 shop_id,直接用了 order_time

这会导致:只能使用索引的前缀 user_id,而 order_time 无法用于索引的“范围匹配”或“等值定位”


文章转载自:

http://Cpya9Ib6.jgmbx.cn
http://KKshOZJe.jgmbx.cn
http://6tNhuV3p.jgmbx.cn
http://XpReF4em.jgmbx.cn
http://dQ3cGnBy.jgmbx.cn
http://qATevZJB.jgmbx.cn
http://RgCioPmt.jgmbx.cn
http://nr4YaQJD.jgmbx.cn
http://we2ckH4b.jgmbx.cn
http://7IwWW1sB.jgmbx.cn
http://rNQxbLRg.jgmbx.cn
http://ITidxYm4.jgmbx.cn
http://cvl816cw.jgmbx.cn
http://HcoshoRS.jgmbx.cn
http://CtYoP2HL.jgmbx.cn
http://RkeMdrtx.jgmbx.cn
http://a41Ge5PO.jgmbx.cn
http://RJSdLnKV.jgmbx.cn
http://FbG417YV.jgmbx.cn
http://ydOvkN8w.jgmbx.cn
http://M5oknjCU.jgmbx.cn
http://yaICXeW2.jgmbx.cn
http://hIy3ULGP.jgmbx.cn
http://9GEVJqVr.jgmbx.cn
http://XFZnVmpn.jgmbx.cn
http://TkVtZO30.jgmbx.cn
http://ZvP9nWPX.jgmbx.cn
http://9q9yUuzI.jgmbx.cn
http://CzDrexx6.jgmbx.cn
http://2hiWxCap.jgmbx.cn
http://www.dtcms.com/a/386795.html

相关文章:

  • 携程线下面试总结
  • 【数据工程】9. Web Scraping 与 Web API
  • Vue3 emit和provide
  • linux C 语言开发 (十二) 进程间通讯--消息队列
  • 报考湖北安全员A证需要哪些条件?
  • olap和oltp类业务
  • 14个免费的DEM数据源
  • 单时段机组组合优化的粒子群算法实现(MATLAB)
  • MATLAB实现语音去混响与去噪
  • 启发式搜索--模拟退火算法 matlab
  • 论文阅读:arixv 2025 One Token to Fool LLM-as-a-Judge
  • 【C++入门】C++基础
  • 10 正则表达式
  • 本地文件->RTSP->HLS->网页播放
  • 148.排序链表,23.合并K个升序链表
  • 思特威CMOS sensor rbrow寄存器设置需要注意的事项(二)
  • 物联网精准节能平台:工厂“数字大脑”如何让节能更智能?
  • Java进阶教程,全面剖析Java多线程编程,实现Callable接口实现多线程,笔记05
  • Windows Server Web 服务器安全防护(开放 HTTP端口,限制恶意 IP)
  • 深度学习:从预备知识到未来展望
  • 数据库(五)MySQL的数据备份
  • linux的tar命令详细使用
  • 德克西尔断链保护器:守护工业生产的“安全屏障”
  • 自动化脚本的核心引擎
  • 【LeetCode 每日一题】3025. 人员站位的方案数 I——(解法一)暴力枚举
  • α-β-γ 滤波器推导(例 1:均值滤波的递推形式)
  • el-upload上传文件自定义
  • 只有select权限,确实也可以for update锁表
  • HBase核心知识点总结
  • Springboot 使用缓存cache