什么是索引
索引是一种基于源数据派生出的来的数据结构,可以加快检索速率
索引的组织结构
hash索引
基于hash实现的O1时间复杂度查询,缺点比较明显只支持等值查询,而且要解决hash冲突
b+树索引
b+树是一个N叉树,每个节点有N个关键字N棵子树,叶子节点存放实际数据而且叶子节点是用链表串起来的,非叶节点存放key。优点logNch查询,支持范围查下,缺点就是频繁的插入删除会导致叶的分裂与合并
为什么不是红黑树,是B+树
mysql的数据都是持久化再磁盘的,每次读取数据都需要通过磁盘IO把数据从磁盘读到内存,而磁盘IO次数又取决于树的高度,B+树的高度是远低于红黑树的,并且B+数的叶子节点是有些且通过链表串起来的,支持范围检索,而红黑树的范围检索只能走中序遍历来得到结构
索引的优化
- 由于B+树中的key是按照关键字从左到右排序,并且比较是先按k1,k2,k3比较来确定是向左节点还是向右节点的,不能跳过k1,直接比较k2,这就是最左原则
- 不能使用左模糊匹配来,这样也不符合最左原则
- 比较不能使用二义性的词,比如!=,not null,not in等
- 不能对索引字段使用函数,这样会破坏key的原有的索引结构
- 对于varchar字段通过整形比较,因为int没法强转为String
- 可以通过索引覆盖来避免回表
- 可以通过索引递推来减少回表
- 可以通过MRR,把离散的回表读改进为循环读
索引的创建原则
- 索引是一种空间换时间的策略,所以不宜创建多
- 由于每个页的大小是16KB如果索引字段过多过大会导致,每个节点的key变少,导致树变高
- 区分度一定要高,如果区分度比较低那边索引的过滤数据的能力越低
- 可以适当使用前缀索引来减少索引的长度 比如index index_email(email(6));
order by的过程
全字段排序
直接获取全部数据,然后把数据放到sort buffer中,按照order by中的关键字排序返回。如果sort buff不够则会进行外部排序
主键排序
不会把数据全部加载到sort buffer中,而是把主键和order by中的关键字排序,然后再跟进主键进行一次回表
order by也是会使用到索引的,请注意