索引数据结构
B+树
哈希索引
常见索引
- 聚集索引(主索引):
按照每张表的主键构造B+树
叶节点为数据页
每个数据页通过双向链表进行链接
对于主键的排序查找和范围查找速度很快
- 非聚集索引(辅助索引):叶节点只能获得主键索引的主键,通过主键的聚集索引再获得行记录
稠密索引:每个搜索码值都有一个索引项
稀疏索引:通常只为一个块中第一个记录建立索引
多级索引
查询语句从索引中就能够取得条件:select字段包含在索引字段中;where条件不能有like操作
B+树与B树
B+树
高度通常为2-3层
索引可以索引整个列数据,也可以只索引一个列开头部分数据
叶节点指向文件记录
B树
搜索码只出现一次
非叶节点为每个搜索码增加一个指针指向文件记录或者对应的桶
- B树与B+树比较:
B树非叶节点存储的搜索码少,更深。某些搜索码查询比B+树快,另一些更慢
B树删除更加复杂
B树略微有空间优势
- MySQL索引问题:
对于索引的添加或者删除,先创建临时表
把数据导入临时表,删除原表,再把临时表重命名为原表
耗时
- InnoDB支持快速索引创建方法:
只限定于辅助索引
创建时,对表加上S锁(只读)
删除,将空间标记可用并删除内部视图上对于索引的定义
- cardinality:表示索引中唯一值的数目的估计值,优化器根据该值判断是否使用索引
索引使用
当访问高选择性(可取值范围广,几乎没有重复)字段并从表中取出很少一部分行时,对该字段添加B+树索引很有必要
- 预读取技术:通过一次IO请求将多个页预读取到缓冲池中
随机预读取(差):当一个区中13个页也在缓冲区中,并且页频繁访问,则将这个区中剩余页预读到缓冲区
线性预读取:如果一个区中的24个页都被顺序访问了,则读取下一个区所有的页
辅助索引的优化:InnoDB存储引擎会先判断是否能从叶节点得到所需数据
联合索引:可以对第二个键值进行排序
哈希索引
冲突机制:链表法
哈希函数:将关键字转换成自然数,然后通过除法散列方式实现
静态散列:桶数量固定
桶溢出解决:
闭地址散列结构:为桶增加溢出桶组成的溢出链
开地址散列结构:1.当桶满了之后,插入到初始桶集合的其他桶中;
2.计算更多散列函数
- 动态散列:
可扩展散列:
多个桶可共享存储块
几个连续的表项可能指向同一个桶
将散列函数的值转化为N个二进制位,用前i位表示桶数目,i随着记录数量动态变化
桶满了需要分裂时:
当桶地址表只有一个项,需要增加桶地址表大小,此时,i加1
当桶地址表中有多个项指向桶,则分配新桶
多哈希表:
多个哈希表共享一个散列函数,相当于一个值对应多个目录项
线性散列:各个桶轮流进行分裂,当一轮分裂完成之后,进入下一轮分裂
- 散列索引和顺序索引比较:
当查询某个确定值时,散列索引更优
当进行范围查询时,顺序索引更优
位图索引
由关系r上属性A的每个值建立的位图构成
对于一个值v,记录i如果取值为v,则位图中第i位位1,否则为0