复合索引字段顺序需按查询需求设计:等值查询字段优先左置,高选择性字段(如user_id)应在前;范围查询字段(如create_time > ?)须置于等值字段之后;order by字段可追加索引末尾以避免排序。

复合索引字段顺序不是随便排的,关键看查询怎么用。顺序设计不合理,索引可能完全失效,甚至拖慢查询。
优先放等值过滤列
WHERE 条件中使用 = 或 IN 的字段,过滤性强、能快速缩小数据范围,应放在最左边。
- 例如高频查询是
WHERE user_id = 123 AND status = 'paid',user_id 是主键或唯一值,选择性极高,status 只有少数几个取值——那索引必须是(user_id, status),而不是反过来。 - 如果先按低选择性字段(如 status)排序,B+树会先扫出大量“paid”记录,再逐个比对 user_id,效率极低。
高选择性字段靠左
选择性 = COUNT(DISTINCT col) / COUNT(*),越接近 1 越好。它决定了单列能筛掉多少行。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 手机号、订单号、创建时间(带毫秒)通常选择性高;性别、状态、类型字段选择性低。
- 比如
(create_time, user_id)和(user_id, create_time)都支持WHERE user_id = ? AND create_time > ?,但前者在user_id等值时无法利用create_time排序优势,后者还能顺便满足ORDER BY create_time,避免额外排序。
范围查询列往后放
>、 属于范围查询,一旦出现,其右侧所有字段都无法走索引。
- 查询
WHERE user_id = 456 AND create_time > '2024-01-01' AND amount > 100,应建(user_id, create_time, amount)。 - 若写成
(create_time, user_id, amount),create_time > ...会让user_id和amount全部失效——因为 B+树在范围扫描后,后续列已失去有序性。
兼顾 ORDER BY 和 GROUP BY
如果查询带排序或分组,且字段已在 WHERE 条件中,可把它们顺延加到索引末尾,实现“索引覆盖 + 免排序”。
-
WHERE category = 'book' ORDER BY price DESC LIMIT 10→ 索引(category, price)不仅能定位,还能直接按 price 倒序返回,不用临时文件排序。 - 注意:ASC/DESC 要和索引定义一致;混合排序(如
ORDER BY a ASC, b DESC)在 MySQL 8.0+ 才原生支持,老版本建议统一方向。










