B 树索引是什么
B+ 树索引是有序数据结构,支持等值、范围、前缀匹配(LIKE 'abc%')与排序,是 MySQL 与 PostgreSQL 的默认索引类型。它的边界也很清晰:在列上做函数运算、使用前置通配符(LIKE '%abc')、两侧类型不一致,都可能让索引无法定位范围。
基本信息
| 支持的操作 | =、>、>=、<、<=、BETWEEN、IN、ORDER BY、LIKE 前缀匹配 |
|---|---|
| 不支持 | 前置通配、列上函数或表达式、类型隐式转换 |
| 复合索引 | 遵循最左前缀原则,前导列缺失时后续列难以独立使用 |
| 排序 | 索引顺序与 ORDER BY 一致时可省去额外排序步骤 |
| 代价 | 占存储、增加写入与维护开销,多一个索引就多一次维护 |
| 两库差异 | 基本行为一致,函数索引与部分索引的写法不同 |
能走索引的写法
能走索引的写法
-- 范围查询:B+ 树直接定位区间
SELECT * FROM orders
WHERE created_at >= '2024-01-01' AND created_at < '2024-02-01';
-- 前缀匹配
SELECT * FROM users WHERE name LIKE 'wang%';
-- 过滤加排序:复合索引 (user_id, created_at) 可同时满足
SELECT * FROM orders WHERE user_id = 100 ORDER BY created_at DESC LIMIT 10;走不了索引的写法
走不了索引的写法
-- 列上包函数:索引的有序性被打乱
SELECT * FROM orders WHERE YEAR(created_at) = 2024;
-- 前置通配:索引按前缀有序,'%wang' 没有确定起点
SELECT * FROM users WHERE name LIKE '%wang';
-- 类型不匹配:字符串列与数字比较会触发隐式转换
SELECT * FROM users WHERE phone = 13800000000; -- phone 列是 varchar条件写法与索引可用性
| 条件写法 | 能否用索引 | 原因 |
|---|---|---|
| col = 常量 | 能 | 等值定位 |
| col > 常量 AND col < 常量 | 能 | 区间扫描 |
| col LIKE 'abc%' | 能 | 前缀有序 |
| col LIKE '%abc' | 不能 | 没有确定起点 |
| FUNC(col) = 常量 | 不能 | 列被运算,有序性失效 |
| col = 不同类型的常量 | 视情况 | 隐式转换可能让索引失效 |
典型使用场景
- 高频等值与范围过滤的列上建索引
- 复合索引同时覆盖过滤与排序,一次满足两种需求
- 唯一索引保证业务键的唯一性
- 外键关联列建索引,加快连接与级联操作
- 用执行计划定期验证索引是否真的被用上
- 清理长期未使用的冗余索引,降低写入开销
复合索引讲究最左前缀:索引 (a, b, c) 能用于 WHERE a = ? 与 a = ? AND b = ?,但对单独只用 b 的条件帮助有限。设计时把过滤频率高、选择性好的列放在前面。
索引不是越多越好:每个索引都会放大写入成本、占用缓冲池。上线新索引前先评估查询频率与读写比,并在业务低峰执行建索引操作。