什么时候会考虑用联合索引?如果只有一个条件查就没有建联合索引的必要了么?

文章内容收录到个人网站,方便阅读:hardyfish.top/

Java面试资料(阿里内部资料):

url81.ctfile.com/f/57345181-...

(访问密码:3899)

什么时候考虑使用联合索引?

联合索引(复合索引)是指在多个列上创建的索引,通常适用于以下场景:

  1. 查询涉及多个条件(多个列的 WHERE 过滤)

    • 如果查询涉及多个条件,单列索引可能无法有效利用,而联合索引可以加速查询。
    sql 复制代码
    SELECT * FROM orders WHERE user_id = 1001 AND status = 'shipped';
    • 如果创建 (user_id, status) 的联合索引,查询时可以有效利用索引。
  2. 索引列经常同时出现在查询中

    • 如果 col1col2 经常一起用于 WHERE 过滤、排序或分组,考虑创建 (col1, col2) 联合索引。
  3. 查询需要覆盖索引

    • 如果 SELECT 查询的列都包含在联合索引中,则可以直接使用索引数据 ,避免回表查询,提高性能(覆盖索引)。
    ini 复制代码
    SELECT user_id, status FROM orders WHERE user_id = 1001;
    • 如果存在 (user_id, status) 索引,就可以直接从索引中取数据,无需访问表数据。
  4. 索引顺序符合查询习惯

    • MySQL 索引采用最左前缀匹配原则,联合索引的列顺序影响查询是否能利用索引。

如果只有一个查询条件,是否还需要联合索引?

不一定。主要取决于以下情况:

  1. 该列是否高选择性

    • 如果查询的单个列是高选择性(区分度高,如 user_id),单列索引可能就够了。
    • 如果单列索引的选择性低(如 status 只有几种状态),联合索引可能更好。
  2. 未来查询是否会增加条件

    • 即使现在只用 WHERE col1 = ?,如果未来可能会加入 col2,创建 (col1, col2) 联合索引更合适。
  3. 是否有 ORDER BY GROUP BY 需求

    • 如果 ORDER BY col1, col2GROUP BY col1, col2 也较常见,联合索引有助于优化排序和分组。

示例分析

1. 只查询 user_id

sql 复制代码
SELECT * FROM orders WHERE user_id = 1001;
  • 如果 user_id 选择性高,单列索引 (user_id) 就够了。
  • 如果 status 也是高频过滤项,并且经常 WHERE user_id AND status,可以考虑 (user_id, status) 联合索引。

2. 既查询 user_id 又查询 status

sql 复制代码
SELECT * FROM orders WHERE user_id = 1001 AND status = 'shipped';
  • (user_id, status) 联合索引比单独的 (user_id) 更有效,避免 status 需要额外的过滤。

3. 只查询 status

sql 复制代码
SELECT * FROM orders WHERE status = 'shipped';
  • 如果 (user_id, status) 联合索引存在,但 status 不是最左前缀,索引无法完全使用,可能需要额外的单列索引 (status)

结论

  • 单列查询时,单列索引通常够用,但如果未来可能加条件,联合索引更合适。
  • 查询条件涉及多个列时,联合索引比多个单列索引更高效。
  • 索引设计要考虑:最左前缀原则、查询模式、选择性、覆盖索引等因素。
相关推荐
阿芯爱编程3 分钟前
前端最新面试题
前端·面试
春_10 分钟前
IP范围转IP掩码
java·服务器·网络·tcp/ip
kfepiza14 分钟前
HttpSessionAttributeListener 的用法笔记250417
java·spring boot·笔记·servlet·java-ee·tomcat
_一条咸鱼_27 分钟前
Vue 指令模块深度剖析:从基础应用到源码级解析(十二)
前端·javascript·面试
ademen29 分钟前
关于 IntelliJ IDEA 中频繁出现的 Kotlin 及其核心作用
java·开发语言·kotlin
薯条不要番茄酱35 分钟前
【JavaEE初阶】多线程重点知识以及常考的面试题-多线程进阶(一)
java·前端·java-ee
大苏打seven37 分钟前
Java学习笔记(多线程):ConditionObject 源码分析
java·笔记·学习
苹果酱05671 小时前
redis系列--1.redis是什么
java·vue.js·spring boot·mysql·课程设计
绝无仅有1 小时前
使用 Docker 安装 Elastic Stack 并重置本地密码
后端·面试·github
卷不动的打工仔1 小时前
Ubuntu利用docker搭建Java相关环境问题记录
java·ubuntu·docker