04 | 深入浅出索引(上)
04 | 深入浅出索引(上)
什么是索引
索引就像书的目录一样,为了提高数据的检索速度
索引常见的模型极其利弊
- 哈希表:适用于只有等值查询的情况,区间查询非常慢
- 有序数组:适用于等值查询和范围查询,数据更新慢、效率低
- 搜索树(N叉树):读写性能优秀、适配磁盘的访问模式(按块读取),被广泛应用于数据库引擎
InnoDB 的索引模型
B+树,每一个索引对应一颗 B+ 树
主键索引的叶子节点存储的是整行数据
非主键索引的叶子节点存储的是主键索引的值
基于主键索引和普通索引的查询有什么区别?
通过主键索引获取数据,只需要搜索主键索引对应的搜索树;
通过非主键索引获取数据,需要先搜索非主键索引对应的树获取到对应行的主键值,然后再去搜索主键对应的搜索树,获取到整行数据,这个过程称为回表
索引维护过程
索引的维护牵涉到数据页的分裂和合并,还会出现数据页利用率低下的问题,我们应该尽可能地优化,去避免这种出力不讨好的事
主键的选择
InnoDB要求记录必须有且只能有一个主键,因为数据行的存储顺序就是按主键的顺序来的。
指定自增主键 > 选择第一个非空的唯一索引 > 自动生成一个不可见的ROW_ID
推荐设置自增主键
性能:自增主键保证数据的插入都是递增插入,追加操作不会导致数据页的分裂、合并 存储:整型做主键只需要4个字节,这对比业务中的字段应该更加短小,主键长度越小,那非主键索引的叶子节点存储的数据就越少
为什么要重建索引
由于删除、更新等操作会导致页分裂,使页面利用率变低;重建索引的过程会创建一个新的索引,把数据按顺序插入,这样页面的利用率最高,也就是索引更紧凑、更省空间
问题讨论
对于 InnoDB 表 T,如果你要重建索引 k,你的两个 SQL 语句可以这么写:
alter table T drop index k;
alter table T add index(k);
也可以这么写:
alter table T drop primary key;
alter table T add primary key(id);
对于上面这两个重建索引的作法,说出你的理解。如果有不合适的,为什么,更好的方法是什么?
答案 重建索引 k 的做法是合理的,可以达到省空间的目的。但是,重建主键的过程不合理。不论是删除主键还是创建主键,都会将整个表重建。所以连着执行这两个语句的话,第一个语句就白做了。这两个语句,你可以用这个语句代替:alter table T engine=InnoDB
评论区讨论
Q:B+树的叶子节点存储的是什么?
B+树的叶子节点是page (页),一个页里面可以存多个行