SQL联合索引设计_最左前缀原则详解

10次阅读

联合索引生效关键在于最左前缀原则:必须从定义的最左列开始连续匹配,否则右侧字段失效;如索引 (name,age,sex),where name=’ 张三 ’ and age>20 时 name 和 age 有效,sex 失效。

SQL 联合索引设计_最左前缀原则详解

联合索引不是把几个字段堆在一起就行,关键在“怎么排”和“怎么用”。最左前缀原则就是它的使用铁律:MySQL 只能从索引定义的最左边列开始,连续、不跳过地匹配查询条件,一旦中断,右边的列就失效。

为什么必须从最左列开始?

B+ 树索引是按联合索引字段顺序整体排序的——先按第一列升序,该列相同时再按第二列升序,依此类推。这意味着:

  • 第一列在整个索引中全局有序,数据库能快速定位起始位置
  • 第二列只在第一列值相同的数据块内有序,单独查它无法确定范围
  • 第三列更受限,只在前两列都相同的子块里有序

比如索引是 (name, age, sex),若只写 WHERE age = 25,数据库根本不知道从哪棵子树开始找,只能全表扫描。

哪些查询能真正用上联合索引?

只要满足“连续、从左起”,就能逐级利用索引:

  • WHERE name = '张三' → 用到 name
  • WHERE name = '张三' AND age = 25 → 用到 name、age
  • WHERE name = '张三' AND age = 25 AND sex = '男' → 全部三列生效
  • WHERE name = '张三' AND age > 20name 和 age 有效,sex 因范围查询中断而失效
  • WHERE name = '张三' ORDER BY agename 用于过滤,age 天然有序,避免额外排序

哪些情况会让索引“形同虚设”?

常见三类断点,一踩就失效:

  • 跳过中间列 :如 WHERE name = '张三' AND sex = '男'(缺 age),只有 name 生效
  • 不从最左开始 :如 WHERE age = 25WHERE age = 25 AND sex = '男',完全不走索引
  • 前导模糊匹配 :如 WHERE name LIKE '% 三',破坏排序前提;而 WHERE name LIKE '张 %' 是有效的

字段顺序怎么排才合理?

不能光看单个字段区分度高低,得结合真实查询模式:

  • 高频等值条件优先靠左,比如常查 status = 'paid',就把 status 放第一位
  • 范围查询字段(>、<code>BETWEENLIKE 'xxx%')尽量靠右,避免过早中断
  • 常用排序或分组字段,可接在等值列之后,例如 WHERE status = ? ORDER BY create_time,适合建 (status, create_time)
  • 字段数建议控制在 3 个以内,兼顾查询效率与写入开销

最终是否生效,一定要用 EXPLAINkey_lentype 字段验证,别凭经验猜。

text=ZqhQzanResources