什么时候考虑使用联合索引?
联合索引(复合索引)是指在多个列上创建的索引,通常适用于以下场景:
查询涉及多个条件(多个列的
WHERE
过滤)如果查询涉及多个条件,单列索引可能无法有效利用,而联合索引可以加速查询。
SELECT * FROM orders WHERE user_id = 1001 AND status = 'shipped';
如果创建
(user_id, status)
的联合索引,查询时可以有效利用索引。
索引列经常同时出现在查询中
如果
col1
和col2
经常一起用于WHERE
过滤、排序或分组,考虑创建(col1, col2)
联合索引。
查询需要覆盖索引
如果
SELECT
查询的列都包含在联合索引中,则可以直接使用索引数据,避免回表查询,提高性能(覆盖索引)。
SELECT 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
SELECT * FROM orders WHERE user_id = 1001;
如果
user_id
选择性高,单列索引(user_id)
就够了。如果
status
也是高频过滤项,并且经常WHERE user_id AND status
,可以考虑(user_id, status)
联合索引。
2. 既查询 user_id
又查询 status
SELECT * FROM orders WHERE user_id = 1001 AND status = 'shipped';
(user_id, status)
联合索引比单独的(user_id)
更有效,避免status
需要额外的过滤。
3. 只查询 status
SELECT * FROM orders WHERE status = 'shipped';
如果
(user_id, status)
联合索引存在,但status
不是最左前缀,索引无法完全使用,可能需要额外的单列索引(status)
。
结论
单列查询时,单列索引通常够用,但如果未来可能加条件,联合索引更合适。
查询条件涉及多个列时,联合索引比多个单列索引更高效。
索引设计要考虑:最左前缀原则、查询模式、选择性、覆盖索引等因素。