717 words
4 minutes
SQL 系列(三):索引原理实战

AI 智能总结

数据库 3 索引原理实战#

索引用于降低查询IO、提升检索速度,是SQL性能优化核心。本文讲解主流索引原理、使用规范,区分三大数据库索引特性差异。

一、B+树、聚簇与非聚簇索引#

绝大多数关系数据库默认索引结构为B+树。

  • B+树特点:所有数据存放在叶子节点,叶子节点链表相连,范围查询高效;非叶子节点仅保存索引键,内存占用小。

聚簇索引 & 非聚簇索引#

  1. 聚簇索引:索引叶子节点直接存放整行数据。
    • MySQL InnoDB独有:主键默认作为聚簇索引,一张表只能一个聚簇索引。
  2. 非聚簇索引(二级索引):叶子节点存储主键值,回表查询获取完整数据。
-- MySQL 创建普通二级索引
CREATE INDEX idx_user_name ON user(name);

方言提醒:Oracle、SQLServer没有聚簇索引概念(SQLServer有聚集索引,概念近似但实现不同)。

二、联合索引与最左匹配原则#

联合索引:多个字段组合建立索引。 最左匹配:查询条件必须匹配索引最左侧起始字段,索引才能生效。

-- 联合索引:(name,age)
CREATE INDEX idx_name_age ON user(name,age);
-- 走索引(满足最左前缀)
SELECT * FROM user WHERE name='test';
SELECT * FROM user WHERE name='test' AND age=20;
-- 索引失效(跳过最左列)
SELECT * FROM user WHERE age=20;

常见索引失效场景#

  1. 字段使用函数运算、隐式类型转换;
  2. 使用 !=、not in;
  3. like '%关键词' 前置通配符;
  4. MySQL不满足最左匹配;
  5. OR连接非索引字段。

三、各类特殊索引#

  • 唯一索引:索引列值不可重复,允许单个NULL
CREATE UNIQUE INDEX idx_phone ON user(phone);
  • 覆盖索引:查询字段全部包含在索引内,无需回表,性能最优
-- 索引(name,age),查询只取name、age,触发覆盖索引
SELECT name,age FROM user WHERE name='test';
  • 全文索引:用于文本模糊检索,替代低效like模糊查询
-- MySQL全文索引示例
CREATE FULLTEXT INDEX idx_content ON article(content);

四、三大数据库索引特色差异#

  1. MySQL(InnoDB) 独有聚簇索引;不支持位图索引;依靠undo log实现MVCC配合索引优化。

  2. Oracle 支持位图索引,适合低基数数据(性别、状态);无聚簇索引。

    位图索引不适合并发DML,容易触发锁冲突。

  3. SQLServer 支持包含列索引,把非索引字段附加到索引,实现覆盖索引,无需拓展联合索引。

-- SQLServer 包含列索引示例
CREATE INDEX idx_name ON user(name) INCLUDE(age,email);

小结#

  1. B+树是通用主流索引结构;联合索引严格遵守最左匹配;
  2. 覆盖索引是日常优化首选,尽量避免回表;
  3. 选型区分数据库特性:聚簇索引认准InnoDB,位图索引使用Oracle,包含列索引为SQLServer方案。
SQL 系列(三):索引原理实战
https://fuwari.vercel.app/posts/sql-series/sql-03-index/
Author
Zero02
Published at
2025-04-15
License
CC BY-NC-SA 4.0