澄清一个概念:innodb中,在聚簇索引之上建立的索引称之为辅助索引,辅助索引访问数据老是须要二次查找,非聚簇索引都是辅助索引,像复合索引、前缀索引、惟一索引,辅助索引叶子节点存储的再也不是行的物理位置,而是主键值mysql
cluster.png算法
因为聚簇索引是将数据跟索引结构放到一块,所以一个表仅有一个聚簇索引sql
聚簇索引默认是主键,若是表中没有定义主键,InnoDB 会选择一个惟一的非空索引代替。若是没有这样的索引,InnoDB 会隐式定义一个主键来做为聚簇索引。InnoDB 只汇集在同一个页面中的记录。包含相邻健值的页面可能相距甚远。若是你已经设置了主键为聚簇索引,必须先删除主键,而后添加咱们想要的聚簇索引,最后恢复设置主键便可。数据库
此时其余索引只能被定义为非聚簇索引。这个是最大的误区。有的主键仍是无心义的自动增量字段,那样的话Clustered index对效率的帮助,彻底被浪费了。缓存
刚才说到了,聚簇索引性能最好并且具备惟一性,因此很是珍贵,必须慎重设置。通常要根据这个表最经常使用的SQL查询方式来进行选择,某个字段做为聚簇索引,或组合聚簇索引,这个要看实际状况。性能
记住咱们的最终目的就是在相同结果集状况下,尽量减小逻辑IO。大数据
image优化
imagespa
MyISM使用的是非聚簇索引,非聚簇索引的两棵B+树看上去没什么不一样,节点的结构彻底一致只是存储的内容不一样而已,主键索引B+树的节点存储了主键,辅助键索引B+树存储了辅助键。表数据存储在独立的地方,这两颗B+树的叶子节点都使用一个地址指向真正的表数据,对于表数据来讲,这两个键没有任何差异。因为索引树是独立的,经过辅助键检索无需访问主键的索引树。3d
看上去聚簇索引的效率明显要低于非聚簇索引,由于每次使用辅助索引检索都要通过两次B+树查找,这不是画蛇添足吗?聚簇索引的优点在哪?
image
因此建议使用int的auto_increment做为主键
image
主键的值是顺序的,因此 InnoDB 把每一条记录都存储在上一条记录的后面。当达到页的最大填充因子时(InnoDB 默认的最大填充因子是页大小的 15/16,留出部分空间用于之后修改),下一条记录就会写入新的页中。一旦数据按照这种顺序的方式加载,主键页就会近似于被顺序的记录填满(二级索引页多是不同的)
聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据必定也是相邻地存放在磁盘上的。若是主键不是自增id,那么能够想 象,它会干些什么,不断地调整数据的物理地址、分页,固然也有其余一些措施来减小这些操做,但却没法完全避免。但,若是是自增的,那就简单了,它只须要一 页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高。
由于MyISAM的主索引并不是聚簇索引,那么他的数据的物理地址必然是凌乱的,拿到这些物理地址,按照合适的算法进行I/O读取,因而开始不停的寻道不停的旋转。聚簇索引则只需一次I/O。(强烈的对比)
不过,若是涉及到大数据量的排序、全表扫描、count之类的操做的话,仍是MyISAM占优点些,由于索引所占空间小,这些操做是须要在内存中完成的。
聚簇索引默认是主键,若是表中没有定义主键,InnoDB 会选择一个惟一的非空索引代替。若是没有这样的索引,InnoDB 会隐式定义一个主键来做为聚簇索引。InnoDB 只汇集在同一个页面中的记录。包含相邻健值的页面可能相距甚远。