Photo by Lorem Ipsum
717 words
4 minutes
SQL 系列(三):索引原理实战
SQL 教程
Posts in this series (10)AI 智能总结
数据库 3 索引原理实战
索引用于降低查询IO、提升检索速度,是SQL性能优化核心。本文讲解主流索引原理、使用规范,区分三大数据库索引特性差异。
一、B+树、聚簇与非聚簇索引
绝大多数关系数据库默认索引结构为B+树。
- B+树特点:所有数据存放在叶子节点,叶子节点链表相连,范围查询高效;非叶子节点仅保存索引键,内存占用小。
聚簇索引 & 非聚簇索引
- 聚簇索引:索引叶子节点直接存放整行数据。
- MySQL InnoDB独有:主键默认作为聚簇索引,一张表只能一个聚簇索引。
- 非聚簇索引(二级索引):叶子节点存储主键值,回表查询获取完整数据。
-- 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;常见索引失效场景
- 字段使用函数运算、隐式类型转换;
- 使用
!=、not in; like '%关键词'前置通配符;- MySQL不满足最左匹配;
- 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);四、三大数据库索引特色差异
-
MySQL(InnoDB) 独有聚簇索引;不支持位图索引;依靠undo log实现MVCC配合索引优化。
-
Oracle 支持位图索引,适合低基数数据(性别、状态);无聚簇索引。
位图索引不适合并发DML,容易触发锁冲突。
-
SQLServer 支持包含列索引,把非索引字段附加到索引,实现覆盖索引,无需拓展联合索引。
-- SQLServer 包含列索引示例CREATE INDEX idx_name ON user(name) INCLUDE(age,email);小结
- B+树是通用主流索引结构;联合索引严格遵守最左匹配;
- 覆盖索引是日常优化首选,尽量避免回表;
- 选型区分数据库特性:聚簇索引认准InnoDB,位图索引使用Oracle,包含列索引为SQLServer方案。
SQL 系列(三):索引原理实战
https://fuwari.vercel.app/posts/sql-series/sql-03-index/