Mysql 索引
Mysql 底层为什么要用B+Tree?
主键索引
B-tree 大概特点
添加8条数据
他这里都是排好顺序的 左边的都小于右边的 一个节点里面可以有多个元素
B+Tree 大概特点
同样的8条数据 B+Tree 要比B-Tree 多一点 他的非叶子节点都冗余了一份在叶子节点上 冗余后的数据都在我们的叶子节点上面并且有指针。
Mysql 的B+Tree
下图是mysql 官网对Innodb 使用 T+tree 的解释
InnoDB页面结构官网解释
当我们除1024 的时候
正好就是16kb
问题 mysql 到底是在插入的时候做的排序还是在查询的时候做的排序?
假如我们现在查询 select*from t1 where a=5 这条sql 语句会怎样查询是查5次磁盘Io 找到结果放回还是如何查询?
图解 插入的过程
第一张图 我们在执行插入的第一条数据的时候放到了第一个 此时当我们插入第二条数据的时候 主键a 是4 会跟我们第一次插入的数据作比较 此时第二条插入的数据就放到了上面 依次类推 所有的在插入的时候都通过主键索引排序 在InnoDb 中也默认会要求有一个主键索引会递增 如果没有的话也会有唯一索引 或者有一个隐藏索引 我们这个sql 没有要求主键自增所以在插入的时候会比较复杂 但是我们在查询的时候就会变得比较简单 假如说我们在执行 select * from t1 where a=3的时候直接就看主键id 就不会一直去查磁盘IO
问题 如果我们的用户数据区域越来越多的时候我们要执行一条 select * from 他 where a=3000的时候如何查询?
这个时候如果我们还只是在用户数据区域查询的话就会很麻烦就用到了我们的页目录
这个时候就想一本书 如果你想查看地200多页的话 直接去目录上面找就可以 所以Mysql 在官网也有所解释
大概意思就每6条记录就是添加到页目录里面 会给一个标识 这个标识就是每个6条里面最小的id 这样查询的时候就直接可以去我们的页目录里面查询。
这里体现了一个思想就是空间可以换时间就算没有页目录也是可以工作的只不过会比较慢但是加一个空间的话就会更快一点
但是我们一页只有16kb 总会满的 这个时候就会再来一页
如果接着插入数据的时候就会形成这样
同样的道理跟上面一样我们还可以用空间换时间的概念 就把第一页最小的组件存到这里
这样我们查询的时候就会简单不用一直查磁盘IO
到这里就发现 就像一个B+Tree 跟mysql 官网说的Tree 一样了 大概解释了一下mysql 的 B+Tree 的生成的过程。
但是也仅仅是查询的是主键的值 如果查的是select*from t1 where b=6
这样的话只能去全表扫描
查询select*from t1 where a>6执行的过程
这样这条执行的时候就是先去找到a=6 的时候 那么右边的都是大于6的了。
联合索引
假设 bcd 是我么的联合索引下面。我们就要用bcd 的字段去排序形成下面的B+Tree
最下面存储是我们的主键 当我们找到数据 最后可以用主键去回表到我们主键的B+Tree 里面去查找到具体数据
结合实际
最左前缀原则
创建联合索引
-- 创建联合索引
create index idx_t1_bcd on t1(b,c,d)
EXPLAIN select * from t1 where b=1 and c=4 and d=2;
查询结果
用到了我们的联合索引
但是当我们执行
EXPLAIN select * from t1 where c=4 and d=2;
结果
没有用到索引用的是全局扫描
我们在执行
EXPLAIN select * from t1 where b=1 and c=4;
用到了我们的联合索引
说明mysql 联合索引遵循最左前缀原则就是假如说b 字段你没有给相当于是cd去B+Tree 里面查找他就不知道改如何去查找了 但是当你给了bc就可以去B+Tree 里面去查找数据。