数据库索引高频面试题及解析
1. 索引有哪些常见类型?
- B+树索引:平衡多路搜索树结构,时间复杂度 O ( log n ) O(\log n) O(logn),支持范围查询
- 哈希索引:基于哈希表实现,时间复杂度 O ( 1 ) O(1) O(1),仅支持等值查询
- 全文索引:用于文本字段的模糊匹配
- 空间索引:处理地理空间数据(如MySQL的R-Tree)
# B+树结构示例
class BPlusTreeNode:
def __init__(self, keys=[], children=[]):
self.keys = keys # 索引键值
self.children = children # 子节点指针
2. B树与哈希索引的核心区别?
特性 | B树索引 | 哈希索引 |
---|---|---|
查询类型 | 范围查询 | 仅等值查询 |
排序支持 | 保持数据有序 | 无序 |
磁盘I/O | 优化顺序访问 | 随机访问 |
时间复杂度 | O ( log n ) O(\log n) O(logn) | O ( 1 ) O(1) O(1) |
3. 什么是"最左前缀原则"?
当建立组合索引(a,b,c)时:
- 有效查询:
WHERE a=1
,WHERE a=1 AND b>2
,WHERE a=1 ORDER BY b
- 无效查询:
WHERE b=2
,WHERE c=3
,WHERE a=1 AND c=3
索引结构示意图: R o o t → ( a ) → ( b ) → ( c ) 索引结构示意图:\\ Root \rightarrow (a) \rightarrow (b) \rightarrow (c) 索引结构示意图:Root→(a)→(b)→(c)
4. 哪些情况会导致索引失效?
- 对字段进行运算:
WHERE YEAR(create_time) = 2023
- 类型转换:
WHERE id = '100'
(id为整型) - 前导通配符:
WHERE name LIKE '%张'
- OR条件未全覆盖:
WHERE a=1 OR b=2
(仅a有索引) - 数据分布倾斜:当>90%数据满足条件时可能全表扫描
5. 覆盖索引如何提升性能?
当查询所需字段全部包含在索引中时:
- 避免回表操作
- 减少磁盘I/O
- 示例:索引
(age,name)
可覆盖SELECT name FROM users WHERE age>20
6. 索引的优缺点分析
优点:
- 查询速度提升 10 2 10^2 102~ 10 5 10^5 105倍
- 加速表连接操作
- 保证数据唯一性(唯一索引)
缺点:
- 占用额外存储空间(约增加20%-30%)
- 降低写操作速度(需维护索引结构)
- 增加优化器选择时间
7. 聚簇索引 vs 非聚簇索引
聚簇索引 | 非聚簇索引 | |
---|---|---|
数据存储 | 叶子节点存储完整数据行 | 叶子节点存储主键值 |
数量限制 | 每个表仅1个 | 可创建多个 |
插入性能 | 主键顺序插入更快 | 随机插入可能产生页分裂 |
典型实现 | MySQL的InnoDB主键索引 | MySQL的MyISAM索引 |
8. 索引维护注意事项
- 定期执行
OPTIMIZE TABLE
消除碎片 - 使用
ANALYZE TABLE
更新统计信息 - 监控索引使用率(通过
SHOW INDEX_STATISTICS
) - 删除冗余索引(工具:pt-duplicate-key-checker)
高频考点扩展
- 索引下推:MySQL 5.6+将WHERE条件推送到存储引擎层处理
- 索引合并:对多个单列索引的条件进行组合优化
- 自适应哈希索引:InnoDB自动为热点数据创建哈希索引
- 索引选择算法:基于基数估算(cardinality)的成本模型
实际案例:某电商平台对
order_time
和user_id
建立组合索引后,查询速度从2.3s提升至0.02s,索引大小从800MB增至1.2GB,写操作延迟增加15%