MySQL索引及其实现原理

MySQL索引及其实现原理


初始索引

为什么有索引

  • 一般情况下,读写比例为10:1左右,对查询操作的优化为重点,可以使用索引加速查询.

索引的原理

简介

通过不断缩小想要查找数据的范围筛选出最终想要的结果.将随机的事件变成顺序事件.

为什么不用简单的搜索树?

  • 磁盘读取数据的时间=寻道时间+旋转延迟+传输时间.
  • 寻道时间:5ms左右;旋转延迟:4ms左右;传输时间:零点几毫秒;总的时间约为9ms左右.
  • 执行一次IO操作的时间可以执行越500万条指令.
  • 访问磁盘的成本是访问内存的十万倍左右,简单的搜索树难以满足复杂的场景.
  • 局部预读性原理:当访问一个地址的数据时,其相邻的数据也很快被访问到.
  • 一次IO读取一页(page),一般为4k或8k.

索引的数据结构

要将IO次数控制在常数数量级,就需要高度可控的多路搜索树,而B+树满足要求.

B+树

结构

  • 非叶子结点不存储真实数据,只存储搜索方向的数据项.
  • 一个结点代表一个磁盘块,其中包括几个数据项和一些指针.
  • 通过数据项和对应的指针,可以判断数据所属的范围,从而根据对应的指针向下查找,直到找到对应的叶子结点.
  • 叶子结点保存对应的完整数据项.

B+树查找过程

  1. 首先由根结点中数据项与待查找数据的关系,判定哪个指针所所指向的方向包含待查找的数据.(一次IO,从磁盘将根结点读入内存)
  2. 将指针指向的结点(磁盘块)读入磁盘,再次从中判定待查找到数据在在哪个指针所指向的结点中.(第二次IO)
  3. 再次将指向的磁盘块读入内存,获得数据.(第三次IO,一般情况下三次IO足够满足百万级的数据)

B+树性质

  • IO次数取决于B+树的高度.当数据表的数据为N,每个磁盘块的数据项的个数是m,则有h=log_(m+1)N.
  • 当N一定时,m越大,h越小.
  • m=单个磁盘块的大小/数据项的大小.
  • 磁盘块的大小=一个数据页的大小,是固定的.
  • 当数据项占的空间越小,数据项越多,则树的高度越低.
  • 索引字段要尽量小,从而可以降低树的高度.
  • 索引的最左匹配特性:对于联合索引,B+树遵循从左到由的原则,先比较最左边的字段,再确定下一步搜索方向.

慢查询优化

建立索引的注意事项

  1. 最左前缀匹配原则: 对于联合索引,MySQL会从左到右一直匹配到范围查询(<,>,between,like).一般将范围查询字段放在联合索引的最后
  2. =和in可以乱序.联合索引中,使用=的多个字段可以乱序.
  3. 尽量使用区分度高的列作为索引.区分度:count(distinct col)/count(*),表示字段不重复的比例.比例越大则需要查找的记录越少.唯一键区分度为1,性别等区分度几乎为0.
  4. 索引列不能参加计算,保持列的"整洁".否则进行索引时,还需要将所有数据使用函数计算后才能比较,成本高.
  5. 尽量扩展索引,而不要新建索引.若已有一个索引,则在旧的索引上进行扩展.
原文地址:https://www.cnblogs.com/truestoriesavici01/p/13224761.html