索引
二叉查找树
- 查找效率:O(logn)
- 在数据量多的情况下,会造成二叉树层数过多,增加io次数(每切换一层二叉树节点增加一次io次数)
- 查找的io次数过多,相对会频繁发生删除新增数据对树结构调整的次数,消耗过多的数据库资源
- 每个节点存储的数据过少,只有左右两个孩子
B树
-
-
定义1:根节点至少包括两个子节点
-
定义2:树中每个节点最多含有m个孩子(m>=2)
-
定义3:除根节点和叶子节点外,其他每个节点至少有ceil(m/2)个孩子 (取上限3=3/2)
-
定义4:所有叶子节点都位于同一层
-
以上定义的目的,尽可能的让每个节点多存储索引信息,尽可能减少树的高度,尽可能减少io的次数
-
定义1:每个关键字排列的顺序必须为升序
-
定义2:任何一个节点的关键字的个数必须至少比它的孩子数少一个如关键字8,12的孩子树为三个p1,p2,p3
-
定义3:其中p1的value数为小于关键字k1(即8)的数,其中p[m]指向了关键字k[m-1]的数(即大于关键字12),其他的pi就是开区间(k[i-1],k[i])的子树
B+树
-
-
定义1:非叶子节点的子树指针与关键字个数相同, 就是每个节点的关键字数与孩子数相同,与b树相比关键字数量等于孩子数量,b树是关键字数<=孩子shu-1,B+树能存储更多的关键字更短的深度
-
定义2:非叶子节点的子树指针p[i],指向关键字值左闭右开k[i]-k[i+1]范围的子树或者值
-
定义3:非叶子节点仅用来存储索引,数据都保存在叶子节点当中,这样可以存储更多的关键字,
-
定义4:所有的叶子节点均有一个链指针按照顺序指向下一个节点,这样在做范围查询的时候也可以使用到该索引
-
结论:
- 1.B+树磁盘读写代价更低,每一个关键字只存放的索引指针数据,相对b树占用的空间更小
- 2.B+树的查询效率更加稳定,因为所有详细数据都是存储在叶子节点中的,所以导致每次的查询效率是相同的,可以实现稳定的O(logn)查询
- 3.更有利于对数据库的扫描,对范围类型的查询有更高的性能,从根节点找到范围查询的叶子节点开始处,根据条件直接链式的遍历进行查找
Hash索引
-
-
理论上查询效率要高于B+树索引
-
寻找逻辑
- 把key进行hsah运算得到一个id,在buckets桶中根据Id找到对应的entries目录,然后一个一个进行比较找到该值
-
缺点:
- 1.只能满足’=’’,in’查询,不能使用范围查询
- 2.不能做排序操作,Hash运算后值的大小关系不能作排序操作
- 3.在进行联合索引查询(组合索引查询的时候),在多个键组成的hash索引中如果只包含部分键进行查询时,不会触发索引查询
- 4.不能避免表扫描,多个key值hash之后可能会出现相同hash值.在出现多条的情况下还要找到对应行数据再来进行比较
- 5.在存在大量hash值相等的情况下,一个buckets hash值存储的行数据就会特别多,这样的效率反而不一定比b+树高,如性别
延申出的问题:
- 1.如何定位并优化慢查询sql
- 2.什么样的信息能成为索引
- 3.索引的数据结构
- 4.密集索引和稀疏索引的区别