聚簇索引:将数据存储与索引放到了一块,索引结构的叶子节点保存了行数据算法
非聚簇索引:将数据与索引分开存储,索引结构的叶子节点指向了数据对应的位置缓存
在innodb中,在聚簇索引之上建立的索引称之为辅助索引,非聚簇索引都是辅助索引,像复合索引、前缀索引、惟一索引。辅助索引叶子节点存储的再也不是行的物理位置,而是主键值,辅助索引访问数据老是须要二次查找。oracle
聚簇索引具备惟一性,因为聚簇索引是将数据跟索引结构放到一块,所以一个表仅有一个聚簇索引。大数据
表中行的物理顺序和索引中行的物理顺序是相同的,在建立任何非聚簇索引以前建立聚簇索引,这是由于聚簇索引改变了表中行的物理顺序,数据行 按照必定的顺序排列,而且自动维护这个顺序;ui
聚簇索引默认是主键,若是表中没有定义主键,InnoDB 会选择一个惟一且非空的索引代替。若是没有这样的索引,InnoDB 会隐式定义一个主键(相似oracle中的RowId)来做为聚簇索引。若是已经设置了主键为聚簇索引又但愿再单独设置聚簇索引,必须先删除主键,而后添加咱们想要的聚簇索引,最后恢复设置主键便可。blog
MyISAM使用的是非聚簇索引,非聚簇索引的两棵B+树看上去没什么不一样,节点的结构彻底一致只是存储的内容不一样而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来讲,这两个键没有任何差异。因为索引树是独立的,经过辅助键检索无需访问主键的索引树。排序
使用聚簇索引的优点:索引
每次使用辅助索引检索都要通过两次B+树查找,看上去聚簇索引的效率明显要低于非聚簇索引,这不是画蛇添足吗?聚簇索引的优点在哪?内存
1.因为行数据和聚簇索引的叶子节点存储在一块儿,同一页中会有多条行数据,访问同一数据页不一样行记录时,已经把页加载到了Buffer中(缓存器),再次访问时,会在内存中完成访问,没必要访问磁盘。这样主键和行数据是一块儿被载入内存的,找到叶子节点就能够马上将行数据返回了,若是按照主键Id来组织数据,得到数据更快。资源
2.辅助索引的叶子节点,存储主键值,而不是数据的存放地址。好处是当行数据放生变化时,索引树的节点也须要分裂变化;或者是咱们须要查找的数据,在上一次IO读写的缓存中没有,须要发生一次新的IO操做时,能够避免对辅助索引的维护工做,只须要维护聚簇索引树就行了。另外一个好处是,由于辅助索引存放的是主键值,减小了辅助索引占用的存储空间大小。
注:咱们知道一次io读写,能够获取到16K大小的资源,咱们称之为读取到的数据区域为Page。而咱们的B树,B+树的索引结构,叶子节点上存放好多个关键字(索引值)和对应的数据,都会在一次IO操做中被读取到缓存中,因此在访问同一个页中的不一样记录时,会在内存里操做,而不用再次进行IO操做了。除非发生了页的分裂,即要查询的行数据不在上次IO操做的换村里,才会触发新的IO操做。
3.由于MyISAM的主索引并不是聚簇索引,那么他的数据的物理地址必然是凌乱的,拿到这些物理地址,按照合适的算法进行I/O读取,因而开始不停的寻道不停的旋转。聚簇索引则只需一次I/O。(强烈的对比)
4.不过,若是涉及到大数据量的排序、全表扫描、count之类的操做的话,仍是MyISAM占优点些,由于索引所占空间小,这些操做是须要在内存中完成的。
聚簇索引须要注意的地方
当使用主键为聚簇索引时,主键最好不要使用uuid,由于uuid的值太过离散,不适合排序且可能出线新增长记录的uuid,会插入在索引树中间的位置,致使索引树调整复杂度变大,消耗更多的时间和资源。
建议使用int类型的自增,方便排序而且默认会在索引树的末尾增长主键值,对索引树的结构影响最小。并且,主键值占用的存储空间越大,辅助索引中保存的主键值也会跟着变大,占用存储空间,也会影响到IO操做读取到的数据量。
为何主键一般建议使用自增id
聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据必定也是相邻地存放在磁盘上的。若是主键不是自增id,那么能够想 象,它会干些什么,不断地调整数据的物理地址、分页,固然也有其余一些措施来减小这些操做,但却没法完全避免。但,若是是自增的,那就简单了,它只须要一 页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高。
转载: