Mysql实战45讲第4,5 讲学习笔记

深入浅出索引学习笔记

  • 一.索引的常见模型及优缺点
    • 1.1 哈希表
    • 1.2 有序数组
    • 1.3 二叉搜索树
  • 二.InnoDB的索引模型
    • 2.1 主键索引和非主键索引的区别
    • 2.2 基于主键索引和普通索引的查询有什么区别
    • 2.3 索引维护
    • 2.3 基于索引维护,讨论一个案例--- 哪些常见下应该使用自增主键,哪些场景下不应该
    • 2.4 索引覆盖
  • 三.常见问题及答案

一.索引的常见模型及优缺点

1.1 哈希表

优点:哈希表以key-value 存储,这种结构适合等值查询的场景,比如Memached以及其他的NoSql 引擎。
缺点:做区间查询,需要全部扫描

1.2 有序数组

有序数组只适用于静态存储引擎,比如保存一些不会修改的数据
优点:有序数组在 等值查询和区间查询的时候表现都不错。
Mysql实战45讲第4,5 讲学习笔记_第1张图片
我们假设有存储user 的数组,按照身份证递增排序。
等值查询:参照ID_card_n2 对应的名字, 用二分法就能得到,时间复杂度O(log(N))
区间查询:查找身份证号[ID_card_X, ID_card_Y] 区间的user,先用二分法找到ID_card_X, 然后向右遍历,直到查到第一个大于ID_card_Y的身份证号,推出循环。
缺点:更新数据的时候比较麻烦,往中间插入一个记录就必须挪动后面所有的记录,成本太高

1.3 二叉搜索树

二叉搜索树特点:每个节点的左儿子小于父节点,父节点又小于右儿子。但是实际上大多数的数据库存储却并不使用二叉树。索引不止存在内存中,还要写到磁盘上。(100 万节点的平衡二叉树,树高20, 一次查询可能需要访问20个数据块, 读取磁盘20次)这个比较慢,所以 尽量使用N 叉树。
N叉树在读写上的性能优点 以及适配磁盘的访问模式,被广泛的应用在数据库引擎中。

二.InnoDB的索引模型

InnoDB 使用的B+ 树索引模型, 所有的数据都存储在 B+ 树表中。 每一个索引在InnoDB 里面对应一颗B+ 树。

2.1 主键索引和非主键索引的区别

mysql> create table T(
id int primary key, 
k int not null, 
name varchar(16),
index (k))engine=InnoDB;

R1~R5 的(ID,K) 值分别为(100,1),(200,2),(300,3),(500,5),(600,6)
Mysql实战45讲第4,5 讲学习笔记_第2张图片

  • 主键索引的叶子节点存储的是整行数据,在InnoDB 里, 主键索引也被称为聚簇索引(clustered index)。
  • 非主键索引的叶子节点内容是主键的值, 在innoDB 里,非主键索引也被称为二级索引(Secondary index)

2.2 基于主键索引和普通索引的查询有什么区别

  • 如果语句是 select * from T where ID = 500, 即主键查询方式,则只需要搜索ID 这颗 B+树。
  • 如果语句是 select * from T where k=5,即普通索引查询方式,则需要先搜索K 索引树,得到ID 的值为500, 再到ID 索引树搜索一次,这个称为回表。

2.3 索引维护

每一个索引 包含多个page, 下面看一下 B+ Tree Simplified Level
Mysql实战45讲第4,5 讲学习笔记_第3张图片

  • 逻辑移动数据:B+ 树为了维护索引有序性,在插入新值的时候需要做必要的维护。比如上面的记录新插入 ID 的值为400, 就相对比较麻烦, 需要逻辑上挪动后面的数据,空出位置。
  • 页分裂,如果 R5 所在的数据页已经满了, 这个时候需要 申请一个新的数据页,然后挪动部分数据过去,这个过程称为页分裂
  • 页合并, 相邻的两个页由于删除了数据,利用率很低,会将数据页做合并。

2.3 基于索引维护,讨论一个案例— 哪些常见下应该使用自增主键,哪些场景下不应该

  • 性能角度
    自增主键的插入数据模式 符合我们前面提到的递增插入场景,每次插入一条新纪录,都是追加操作,都不涉及到挪动其他记录,也不会触发叶子节点分裂

  • 存储空间角度
    比较以 身份证号做主键和 自增id 做主键为例: 由于每个非主键索引的叶子节点都是主键的值,如果 用身份证号做主键, 那么每个二级索引的叶子节点占用约20个节点,而如果用整型 做主键,则只要4个子节,如果是长整形则只需要8个子节。
    主键长度越小, 普通索引的叶子节点就越小,普通索引占用的空间也越小。

有什么场景是比较适合用业务字段直接做主键的呢?
典型的KV 场景: 1. 只有一个索引; 2 该索引 必须是唯一索引。

2.4 索引覆盖

三.常见问题及答案

你可能感兴趣的:(mysql)