联合索引有什么作用,给三个字段添加一个索引和分别给这三个字段对应添加索引,有什么区别?
联合索引(复合索引)通过将多个列组合在一个索引中,可优化多列查询、避免回表、提升排序效率,并支持最左前缀匹配。相比单独索引,联合索引存储空间小、写入性能好,在多列查询时效率更高;但单独索引在非最左前缀查询时更具优势。实际应用中应根据查询模式选择:高频多列查询用联合索引,多变单列查询用单独索引,也可混合使用。设计时需考虑列的选择性、查询场景和读写比例,并通过EXPLAIN验证索引使用情况。
一、联合索引的作用
联合索引(也称复合索引、组合索引)是指在一个索引中包含多个表中的列。你可以把它想象成一本电话簿,它不是单纯按“姓”或者按“名”排序,而是先按“姓”排序,在“姓”相同的情况下再按“名”排序。
它的主要作用有:
-
优化多列查询条件:当你的
WHERE子句中同时使用了索引中的多个列时,联合索引可以极大地提高查询效率。例如,索引是(last_name, first_name),查询是WHERE last_name = 'Smith' AND first_name = 'John',这个索引就能精准定位。 -
避免回表(Covering Index):如果查询的所有字段都包含在联合索引中(即索引包含了要查询的列和条件列),数据库可以直接从索引中获取所有数据,而无需再回到主表(数据文件)中去查找。这被称为“覆盖索引”,性能提升非常显著。
-
优化排序(ORDER BY):如果
ORDER BY子句的顺序与联合索引的创建顺序一致(或相反,但需指定 DESC),数据库可以直接利用索引的有序性来避免额外的排序操作。例如,索引是(A, B),查询是ORDER BY A, B或ORDER BY A DESC, B DESC,就可以利用索引排序。 -
优化最左前缀匹配查询:这是联合索引最重要的特性。即使查询没有使用索引中的所有列,只要使用了从最左边开始的连续列,索引仍然可能生效。例如,索引是
(A, B, C):-
WHERE A = 1(生效) -
WHERE A = 1 AND B = 2(生效) -
WHERE A = 1 AND B = 2 AND C = 3(生效) -
WHERE B = 2(不生效,因为跳过了最左边的 A) -
WHERE A = 1 AND C = 3(部分生效,索引只会用到 A 列来筛选,C 列用不上)
-
二、一个联合索引 vs 三个单独索引的区别
这是问题的关键。我们通过一个具体的例子来说明,假设我们有一个 users表,有三个字段:country, city, age。
-
方案一:一个联合索引
idx_combined (country, city, age) -
方案二:三个单独索引
idx_country (country),idx_city (city),idx_age (age)
区别对比表
|
特性 |
一个联合索引 |
三个单独索引 |
|---|---|---|
|
索引结构 |
一棵B+树,数据按 (country, city, age) 的顺序排序。 |
三棵独立的B+树,分别按 country、city、age 排序。 |
|
存储空间 |
较小。只有一个索引,占用空间少。 |
较大。有三个索引,占用空间约是联合索引的3倍。 |
|
写入性能 |
较好。插入、更新、删除数据时,只需要维护一个索引。 |
较差。需要维护三个索引,写操作开销更大。 |
|
查询场景1:等值查询 |
效率极高。可以利用索引的精确定位,快速找到数据。是联合索引的最佳使用场景。 |
数据库优化器通常只能选择一个它认为最优的索引(比如 |
|
查询场景2:最左前缀查询 |
效率高。完全符合最左前缀原则,索引完全有效。 |
对于 |
|
查询场景3:非最左前缀查询 |
索引失效。因为跳过了最左边的 |
可以生效。对于 |
|
排序优化 |
效率高。可以直接利用索引的有序性,无需额外排序。 |
效率低。数据库需要将数据取出后进行额外的排序操作(Using filesort),如果数据量大,会非常慢。 |
三、如何选择?实践建议
没有绝对的优劣,关键在于你的查询模式。
应该优先使用联合索引的情况:
-
你的查询条件经常同时使用多个字段进行过滤(特别是等值查询)。
-
你需要对多个字段进行排序,并且排序顺序与索引顺序一致。
-
你希望实现覆盖索引,避免回表,追求极致查询性能。
例如:你的业务中大部分查询都是 WHERE country='XX' AND city='XX',那么建立 (country, city)的联合索引是最佳选择。
考虑使用多个单独索引的情况:
-
你的查询条件变化多端,且经常单独使用各个字段作为条件。
-
某个字段的选择性非常高(几乎唯一),为其建立单独索引的价值很大。
例如:你的业务中,有的查询只用 country,有的查询只用 city,有的查询只用 age,很少有组合查询。那么建立三个单独索引可能更合适。
更高级的策略:混合使用
在实际生产中,通常会采用混合策略,根据最频繁、最耗时的查询来设计索引。
-
为最核心的联合查询建立联合索引:比如为
(country, city, age)建立一个索引。 -
为高频的单列查询建立单独索引:如果
city的单查也非常多,可以再单独为city建立一个索引。但这会增加存储和写入开销,需要权衡。
总结一下核心原则:
-
高选择性的列放在联合索引的左边(即区分度高的列,如用户ID,放在区分度低的列,如性别,前面)。
-
遵循最左前缀原则 来设计索引顺序,以满足你的核心查询场景。
-
权衡读写比例 索引越多,写操作越慢。对于写密集型的表,要谨慎添加索引。
-
使用
EXPLAIN分析你的SQL语句,确认索引是否被正确使用。这是最重要的优化工具。
更多推荐



所有评论(0)