这是我参与「第五届青训营 」伴学笔记创作活动的第 15 天
1. 索引优点与使用场景
索引的优点:
- 索引大大减少了服务器需要扫描的数据量
- 索引可以帮助服务器避免排序和临时表
- 索引可以将随机 I/O 变为顺序 I/O
索引的使用场景:
- 对于非常小的表,大部分情况下全表扫描效率更高。
- 中到大型表,索引非常有效。
- 特大型的表,建立和使用索引的代价会随之增大,可以使用分区技术来解决。
**索引的类型:**索引很多种类型,是在MySQL的存储引擎实现的。
- 普通索引:最基本的索引,没有任何约束限制。
- 唯一索引:和普通索引类似,但是具有唯一性约束,可以允许有空值。
- 主键索引:特殊的唯一索引,不允许有空值。
索引的区别:
- 一个表只能有一个主键索引,但是可以有多个唯一索引。
- 主键索引一定是唯一索引,唯一索引不是主键索引。
- 主键可以与外键构成参照完整性约束,防止数据不一致。
- 联合索引:将多个列组合在一起创建索引,可以覆盖多个列。(也叫复合索引,组合索引)
- 外键索引:只有InnoDB类型的表才可以使用外键索引,保证数据的一致性、完整性、和实现级联操作(基本不用)。
- 全文索引:MySQL自带的全文索引只能用于MyISAM,并且只能对英文进行全文检索 (基本不用)
MyISAM索引与InnoDB索引的区别?
- InnoDB索引是聚簇索引,MyISAM索引是非聚簇索引。
- InnoDB的主键索引的叶子节点存储着行数据,因此主键索引非常高效。
- MyISAM索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据。
- InnoDB非主键索引的叶子节点存储的是主键和其他带索引的列数据,因此查询时做到覆盖索引会非常高效。
2. B+ 树索引
二分查找法
- 将一组数据先升序排序,然后每次比较中点位置的值;若大于则在右半区间查找,否则在左半区间查找。
二叉查找树
- 二叉查找树中,左孩子的值总是小于父亲的值,右孩子的值总是大于父亲的值。
- 二叉查找树可能会不平衡,变成链表。
平衡二叉树
- 符合二叉查找树
- 必须满足任何节点的两个子树的高度之差小于等于1 维护一棵平衡二叉树,需要经常性的旋转操作,开销较大。
B+ 树 由 B 树和索引顺序访问方法 (ISAM) 演化而来。 最下面一层用于存放数,叫做 Leaf Page;上面几层存放索引,叫做 Index Page。 Leaf Page 之间通过双向链表连接起来。
插入操作 平衡扩张
-
Leaf 未满,Index 未满: 直接将记录插入到叶子节点的相应位置中。
-
Leaf 满了,Index 未满: 需要拆分 Leaf Page。将目标页的中间节点放入 Index 中。小于中间节点的放左边 Page;大于等于的放入右边 Page。
-
Leaf 满了,Index 满了: 需要拆分 Leaf Page 和 Index Page。先按 2 操作,然后再防止 中间节点。将Index Page 的中间节点放入上一层的 Index Page。小于中间节点的放左边 Page;大于等于的放入右边 Page。
旋转操作 当前Leaf Page满了,而其左右兄弟 Leaf Page 未满时,进行旋转操作。 将记录移动到其兄弟节点上,并重新更新 Index Page。
删除操作 使用填充因子来控制删除操作,填充因子最小值是 50%。 填充因子 = 有数的节点数目 / 总节点数目。
- Leaf 不小于 填充因子,Index 不小于 填充因子 1.1 要删除的数据不是第一个,直接删除 1.2 要删除的数据是第一个,删除后,更新 Index Page
- ......
在数据库中 B+ 树的高度一般在 2 — 4 层。
2.1. 聚集索引
聚集索引就是按照每张表的主键构造一棵 B+ 树,叶子节点中存放的是整张表的行记录数据。也将聚集索引的叶子节点叫做数据页。 每张表只有一个聚集索引。聚集索引并不是物理上连续的,而是逻辑上连续的。
优点
- 减少磁盘IO
- 数据访问更快
- 使用覆盖索引扫描的查询可以直接使用页节点中的主键值
- 对于主键的范围查找和排序查找速度非常快。
缺点
- 插入速度依赖与插入顺序
- 更新索引的代价很高
- 页分裂问题
- 二级索引变大,因为与主索引有关
- 二级索引查找的次数不只一次
2.2. 辅助索引 (非聚集索引)
辅助索引的叶子节点不包括行记录的全部数据,包含一个键值和书签。 当使用辅助索引来查询数据时,会先通过辅助索引找到指向聚集索引的主键,然后再通过聚集索引来找到完整的记录。
2.3. 联合索引
索引匹配的最左原则具体是说,假如索引列分别为A,B,C,顺序也是A,B,C:
- 那么查询的时候,如果查询【A】【A,B】 【A,B,C】,那么可以通过索引查询
- 如果查询的时候,采用【A,C】,那么C这个虽然是索引,但是由于中间缺失了B,因此C这个索引是用不到的,只能用到A索引
- 如果查询的时候,采用【B】 【B,C】 【C】,由于没有用到第一列索引,不是最左前缀,那么后面的索引也是用不到了
- 如果查询的时候,采用范围查询,并且是最左前缀,也就是第一列索引,那么可以用到索引,但是范围后面的列无法用到索引
2.4. 覆盖索引
如果在一次查询中,如果一个索引包含或者说覆盖所有需要查询的字段的值,则不再需要回表查询。我们就称之为覆盖索引。 要确定一个查询是否是覆盖索引,通过 explain 命令查看 Extra 的结果是否为 Using index。
3. 全文索引
MyISAM 存储引擎支持全文索引,用于查找文本中的关键词,而不是直接比较是否相等。 查找条件使用 MATCH AGAINST,而不是普通的 WHERE。 全文索引使用倒排索引实现,它记录着关键词到其所在文档的映射。
InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持全文索引。
4. 哈希索引
哈希索引查找复杂度为 哈希索引是自适应的,InnoDB 会根据需要添加,不能人为干预。
5. 空间数据索引(R-Tree)
MyISAM表支持空间索引,可以用作地理数据存储。