| 索引的本质 | 用额外空间换查询速度的有序数据结构,代价是写放大 |
| B+ 树为什么合适 | 非叶节点只存键、树矮(3~4 层可存千万级)、叶子链表天然支持范围扫描,磁盘 IO 少 |
| B+ 树 vs B 树 | B 树每个节点都存数据导致扇出小、树更高;B+ 树数据只在叶子且有链表 |
| B+ 树 vs 哈希索引 | 哈希是 O(1) 等值但不支持范围、排序、最左前缀 |
| 聚簇索引 Clustered | 叶子节点直接存整行数据,InnoDB 的主键索引即聚簇索引 |
| 二级索引(辅助索引) | 叶子存主键值,查非索引列需回表 |
| 回表 | 先在二级索引拿到主键,再回聚簇索引取整行,多一次查找 |
| 覆盖索引 Covering Index | 查询所需列全在索引里,免回表;EXPLAIN 的 Extra 出现 Using index |
| 联合索引 | 多列按定义顺序组成一个索引,先按第一列排、再按第二列排 |
| 最左前缀原则 | 联合索引只能从最左列开始连续匹配;中间断掉则后面的列失效 |
| 范围条件的位置 | 范围查询之后的列不再能用于索引定位(但 8.0 有索引下推与跳跃扫描可部分缓解) |
| 索引下推 ICP | 把 WHERE 条件下推到存储引擎在索引层过滤,减少回表次数(Using index condition) |
| 索引跳跃扫描 Skip Scan | 8.0.13+ 在最左列基数很低时也能用上联合索引 |
| 索引失效的典型场景 | 左模糊 %x、列上用函数或运算、隐式类型转换、OR 连接非索引列、!=/NOT IN 有时失效 |
| 选择性与基数 | 区分度 = 不同值数 / 总行数;区分度低的列(性别)单建索引意义不大 |
| 前缀索引 | 长字符串只用前 N 个字符建索引,省空间但不能用于覆盖索引 |
| 索引合并 Index Merge | 优化器用多个单列索引求交/并,通常是联合索引缺失的信号 |
| 冗余与重复索引 | 已有 (a,b) 时再建 (a) 是冗余,白白增加写开销 |
| 索引统计信息 | innodb_stats_persistent 控制持久化统计,统计失真会导致选错执行计划 |