贝利信息

SQL 复合索引的最左前缀原则

日期:2026-01-24 00:00 / 作者:舞姬之光
复合索引必须从最左列开始查,因B+树按索引列顺序逐级排序,仅最左列有序性支持二分查找;跳过则无法定位数据块,导致全表扫描或部分失效。

复合索引为什么必须从最左列开始查?

因为底层是 B+ 树,数据按索引列顺序逐级排序:先排第一列,相同时再排第二列,以此类推。数据库只能靠最左列的有序性快速定位数据块;跳过它,就等于在一本按「姓氏→名字→年龄」排序的通讯录里,直接翻到「名字=John」——根本没法二分查找。

常见错误现象:EXPLAIN 显示 type=ALLkey=NULL,明明建了 INDEX(a,b,c),但 WHERE b = ?WHERE a = ? AND

c = ? 就用不上。

范围查询(>、

无效。最左前缀匹配会在遇到第一个范围条件时“截断”,后续列不再参与索引查找。

比如索引是 (user_id, status, create_time)

怎么安排复合索引的列顺序才不踩坑?

核心逻辑不是“哪些字段常查”,而是“哪些字段能做等值筛选 + 哪些字段要排序/分组/范围过滤”。高选择性(区分度大)的等值列优先放左,范围列尽量靠右。

例如用户表常用查询:WHERE tenant_id = ? AND status = ? ORDER BY updated_at DESC LIMIT 20

索引覆盖和回表是怎么被最左前缀影响的?

只有查询字段全部落在复合索引中,才能触发索引覆盖(避免回表)。但前提是这些字段本身得能被索引“触达”——仍受最左前缀限制。

比如有索引 INDEX(name, age, gender)

容易被忽略的一点:即使满足最左前缀,如果 SELECT * 或查了索引外字段,照样回表——索引覆盖不是自动的,得看 SELECT 列是否“全在索引里”且“能被索引访问到”。