外观
什么是联合索引
⭐ 题目日期:
京东 - 2024/12/26, 小红书 - 2024/11/11
📝 题解:
联合索引(Composite Index),也称为复合索引,是数据库中对多个列组合创建的索引。它通过将多个列的键值按顺序存储在B树或B+树结构中,优化涉及这些列的查询性能。以下是联合索引的核心要点:
一、联合索引的结构
- 存储方式:按索引列的顺序逐级排序(如索引
(A, B, C)
,先按A排序,A相同按B排序,B相同再按C排序)。 - 示例:
表数据:
A | B | C
1 | 3 | 5
1 | 2 | 4
2 | 1 | 3
联合索引 (A, B) 的存储顺序:
(1,2) → (1,3) → (2,1)
二、联合索引的适用场景
1. 多列组合查询
- 等值查询 + 范围查询:
SELECT * FROM orders
WHERE user_id = 1001 AND order_date > '2023-01-01'; -- 索引(user_id, order_date)
2. 覆盖索引(Covering Index)
- 避免回表:索引包含查询所需的所有字段。
CREATE INDEX idx_user_info ON users(name, age, city);
-- 直接通过索引获取数据
SELECT name, age FROM users WHERE city = 'Beijing';
3. 排序/分组优化
- 多列排序或分组:
SELECT * FROM products
WHERE category = 'Electronics'
ORDER BY price DESC, stock ASC; -- 索引(category, price, stock)
三、联合索引的使用限制
1. 最左前缀原则(Leftmost Prefix Rule)
- 规则:查询必须使用索引的最左侧列,否则无法利用索引。
- 示例:
索引 (A, B)是否生效WHERE A = 1 AND B = 2✅ 生效WHERE B = 2❌ 不生效(跳过A)WHERE A > 1 AND B = 2✅ A生效,B仅部分生效
2. 列顺序选择
- 优先级:
- 高基数(高区分度)列在前:更高效过滤数据。
- 等值查询列优先于范围查询列:范围查询后的列无法使用索引。
- 示例:
四、联合索引的优化策略
1. 避免冗余索引
- 场景:已有索引
(A, B)
,则单独索引(A)
冗余,可删除。 - 例外:若需单独查询
B
,需单独建索引。
2. 合理设计列顺序
- 业务场景驱动:根据高频查询条件调整顺序。
-- 高频查询1: WHERE user_id=1001 AND status='paid'
-- 高频查询2: WHERE status='paid' AND product_id=200
-- 最佳索引:根据查询频率选择 (user_id, status) 或 (status, product_id)
3. 监控索引使用率
- 工具:
- 执行计划分析:
EXPLAIN
查看是否命中索引。 - 数据库统计:如MySQL的
INFORMATION_SCHEMA.STATISTICS
。
- 执行计划分析:
- 优化:删除未使用或低效索引。
五、实际案例
案例1:电商订单查询优化
- 表结构:
orders(order_id, user_id, product_id, status, create_time)
- 高频查询:
SELECT * FROM orders
WHERE user_id = 1001 AND status = 'paid'
ORDER BY create_time DESC;
- 索引设计:
(user_id, status, create_time)
- 过滤:快速定位用户ID和状态。
- 排序:直接利用索引有序性,避免Filesort。
案例2:社交应用好友关系
- 表结构:
friends(user_id, friend_id, relation)
- 高频查询:
SELECT * FROM friends
WHERE user_id = 2001 AND friend_id = 3002;
- 索引设计:
(user_id, friend_id)
- 覆盖查询:直接通过索引定位记录,无需回表。
六、总结
联合索引通过 组合多列的排序和过滤能力,显著提升复杂查询性能,但需遵循 最左前缀原则 并合理设计列顺序。其核心价值在于:
- 减少随机I/O:通过索引快速定位数据。
- 避免全表扫描:高效处理多条件查询。
- 优化排序/分组:利用索引有序性减少计算开销。
合理设计联合索引是数据库性能优化的关键手段,需结合业务查询模式动态调整。