🧩 一、索引核心知识(以 MySQL 为主)
1. 为什么需要索引?
- 索引就像书的目录,用来加快查询速度。
- 没有索引,查询数据需要全表扫描,效率低。
2. MySQL 常见索引结构
✅ 主结构:B+Tree
-
默认索引结构(如 InnoDB 的主键索引、二级索引)
-
特点:
- 所有数据只存在叶子节点
- 每个节点存放多个键,磁盘读取次数少
- 适合范围查询、排序、分页
❌ B-Tree vs B+Tree 区别
特性 | B-Tree | B+Tree |
---|---|---|
数据存储 | 所有节点都存数据 | 只叶子节点存数据 |
查询效率 | 每次访问可能命中数据 | 查询路径更稳定 |
范围扫描 | 较差 | 高效 |
✅ Hash 索引(MyISAM / 特殊场景)
- 基于哈希表,只能用于等值查询(=),不支持范围、排序。
- 不常用,因为不适配大多数业务查询。
3. 索引的分类
分类方式 | 类型 | 说明 |
---|---|---|
按字段 | 单列索引、联合索引 | 联合索引顺序影响使用效果 |
按唯一性 | 普通索引、唯一索引 | 唯一索引约束字段不能重复 |
物理结构 | 主键索引、二级索引 | 主键索引包含整行数据(聚簇索引) |
功能 | 覆盖索引、前缀索引 | 覆盖索引避免回表;前缀索引节省空间 |
4. 回表 & 覆盖索引
- 回表:二级索引查到主键,再去主键索引找整行数据(多一次 IO)。
- 覆盖索引:查询字段都在索引里,不需要回表,效率更高。
5. 索引失效常见场景
- 使用
LIKE '%xxx'
模式,无法走 B+Tree 索引 - 使用函数处理字段,如
DATE(create_time)
会导致失效 - 字段类型不一致(int vs string)也会失效
- 联合索引未按最左前缀原则使用
🧠 二、内存结构核心知识(操作系统 & 程序运行原理)
内存结构理解有助于你掌握:
- 程序为什么崩(如栈溢出)
- 内存泄漏、缓存机制、数据库内存优化
1. 程序内存结构(以 C 程序为例)
+-------------------+
| 栈区(Stack) | → 局部变量、函数调用栈帧(自动分配)
+-------------------+
| 堆区(Heap) | → 动态内存 malloc/new(手动释放)
+-------------------+
| BSS段 | → 未初始化的全局变量
+-------------------+
| 数据段(Data) | → 初始化的全局/静态变量
+-------------------+
| 代码段(Text) | → 程序代码
+-------------------+
2. 虚拟内存与物理内存映射
- 每个进程拥有自己的虚拟地址空间(如 4GB)
- 操作系统负责将虚拟地址通过页表映射到物理地址
- 利用分页机制 + 缺页中断 + 页面置换算法实现多进程高效内存共享
3. 内存分页与缓存(CPU 缓存)
- TLB(Translation Lookaside Buffer):缓存页表项,加速虚拟地址转物理地址
- CPU Cache(L1/L2/L3):缓存在 CPU 芯片上的数据块,加速热点数据访问
- 缓存命中率直接影响程序性能
4. Java 内存结构(如果你写 Java)
+--------------------+
| 程序计数器 | 当前线程执行位置
| 虚拟机栈 | 每个线程独立,存储栈帧
| 本地方法栈 | native 方法相关栈帧
| 堆(Heap) | 对象实例所在区域,GC管理
| 方法区(元空间) | 类元信息、常量池
+--------------------+
🚀 三、实际开发中的应用场景
场景 | 索引/内存应用点 |
---|---|
数据库慢查询优化 | 索引结构、覆盖索引、索引选择性 |
JVM 性能优化 | 垃圾回收、堆区调优、逃逸分析 |
大数据量分页 | 避免 offset,使用索引游标(ID > ?) |
C 程序内存泄漏排查 | 堆管理、栈溢出检测 |
多线程内存可见性问题(Java) | JVM 内存模型、volatile、happens-before |
📚 推荐补强资源
-
📖 索引深入:
- 《高性能MySQL》
- B站搜索 “MySQL 索引机制”
-
📖 内存原理:
- 《深入理解计算机系统(CSAPP)》
- 《操作系统真象还原》《现代操作系统》