Mysql技术内幕InnoDB存储引擎读书笔记--《五》索引与算法

B +树索引的管理

目前Mysql数据库存在的一个普遍问题是,所有对于索引的添加或者删除操作,Mysql数据库是先创建一张临时表,然后把数据导入临时表,删除原表,再把临时表重名为原来的表名。因此对于一张大表,添加和删除索引需要很长的时间。
InnoDB存储引擎从版本InnoDB Plugin开始,支持一种称为快速索引创建方法。当然这种方法只限定于辅助索引,对于主键的创建和删除还是需要重建一张表。对于辅助索引的创建,InnoDB存储引擎会对表加上一个S锁。在创建的过程中,不需要重建表,因此速度极快。但是在创建的过程中,由于上了S锁,因此创建的过程中该表只能进行读操作。删除辅助索引的操作就更简单了,只需要在InnoDB存储引擎的内部视图更新下,将辅助索引的空间标记为可用,并删除Mysql内部视图上对该表的索引定义即可。

show index 每个列的含义:

  • Table:索引所在的表名
  • Non_unique:非唯一的索引,可以看到primary key是0, 因此必须是唯一的。
  • Key_name:索引的名称,我们可以通过这个名称来DROP INDEX。
  • Seq_in_index:索引中该列的位置,如果看联合索引idx_a_b就比较直观了。
  • Column_name:索引的列。
  • Collation:列以什么方式存储在索引中。可以是A或者NULL。B+树总是A,即排序的。如果使用了Heap存储引擎,并且建立了Hash索引,这里就会显示出NULL了。因为Hash根据Hash桶来存放索引数据,而不是对数据进行排序。
  • Cardinality:非常关键的值,表示索引中唯一值的数目的估计值。Cardinality表的行数应尽可能接近1,如果非常小,那么需要考虑是否还需要建立这个索引。
  • Sub_part:是否是列的部分被索引。如果看idx_b这个索引,这里显示100,表示我们只索引b列的前100个字符。如果索引整个列,则该字段为NULL。
  • Packed:关键字如何被压缩。如果没有被压缩,则为NULL。
  • NULL:是否索引的列含有NULL值。如果有为YES。
  • Index_type:索引的类型
  • Comment:注释

索引时机

Mysql数据库的优化器会通过EXPLAIN的rows字段预估查询可能得到的行,如果大于某一个值,则B+树会选择全表扫描。一般取出的数据量超过表中数据的20%,优化器就不会使用索引,而是进行全表的扫描。

预读取

InnoDB有两个预读方法,称为随机预读取(random read ahead)和线性预读取(linear read ahead)预读取。随机预读是指当一个区(64个连续页)中的13个页也在缓冲区中,并在LRU列表的前端(即页是频繁的被访问),则InnoDB存储引擎会将这个区中所有页预读到缓冲区。线性预读基于缓冲池中页的访问模式,而不是数量。如果一个区中的24个页都被顺序的访问了,则InnoDB存储引擎会预读取下一个区的所有页。

InnoDB存储疫情的哈希算法

InnoDB存储引擎使用哈希算法对字典进行查找,其冲突机制采用链表方式,哈希函数采用除法散列方式。对于缓冲池页的哈希表来说,在缓冲池中的Page页都有一个chain指针,它指向相同哈希函数值的页。而对于除法散列,m的取值为略大于2倍缓冲池页数量的质数。

InnoDB存储引擎的表空间都有一个space号,我们要查找的应该是某个表空间的某个连续16KB的页,即偏移量offset。InnoDB存储引擎将space左移20位,然后加上这个space和offset,即关键字K=space<<20+offset,然后通过除法散列到各个槽中。

你可能感兴趣的:(数据库)