文章内容收录到个人网站,方便阅读:hardyfish.top/
Java面试资料(阿里内部资料):
url81.ctfile.com/f/57345181-...
(访问密码:3899)
什么时候考虑使用联合索引?
联合索引(复合索引)是指在多个列上创建的索引,通常适用于以下场景:
-
查询涉及多个条件(多个列的
WHERE
过滤)- 如果查询涉及多个条件,单列索引可能无法有效利用,而联合索引可以加速查询。
sqlSELECT * FROM orders WHERE user_id = 1001 AND status = 'shipped';
- 如果创建
(user_id, status)
的联合索引,查询时可以有效利用索引。
-
索引列经常同时出现在查询中
- 如果
col1
和col2
经常一起用于WHERE
过滤、排序或分组,考虑创建(col1, col2)
联合索引。
- 如果
-
查询需要覆盖索引
- 如果
SELECT
查询的列都包含在联合索引中,则可以直接使用索引数据 ,避免回表查询,提高性能(覆盖索引)。
iniSELECT user_id, status FROM orders WHERE user_id = 1001;
- 如果存在
(user_id, status)
索引,就可以直接从索引中取数据,无需访问表数据。
- 如果
-
索引顺序符合查询习惯
- MySQL 索引采用最左前缀匹配原则,联合索引的列顺序影响查询是否能利用索引。
如果只有一个查询条件,是否还需要联合索引?
不一定。主要取决于以下情况:
-
该列是否高选择性
- 如果查询的单个列是高选择性(区分度高,如
user_id
),单列索引可能就够了。 - 如果单列索引的选择性低(如
status
只有几种状态),联合索引可能更好。
- 如果查询的单个列是高选择性(区分度高,如
-
未来查询是否会增加条件
- 即使现在只用
WHERE col1 = ?
,如果未来可能会加入col2
,创建(col1, col2)
联合索引更合适。
- 即使现在只用
-
是否有
ORDER BY
或GROUP BY
需求- 如果
ORDER BY col1, col2
或GROUP 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)
。
结论
- 单列查询时,单列索引通常够用,但如果未来可能加条件,联合索引更合适。
- 查询条件涉及多个列时,联合索引比多个单列索引更高效。
- 索引设计要考虑:最左前缀原则、查询模式、选择性、覆盖索引等因素。