索引这个词在数据库知识中耳熟能详,是一种以空间换取时间的典型,索引结构往往能给数据操作带来十分显著的性能提升,我们都知道大多数的数据库默认的索引结构都是B+树,而聚集索引和非聚集索引(也叫辅助索引)都属于B+树结构;

所以首先我们简单了解下B+树:

B+树:是一种高度平衡的为磁盘数据存取而设计的查找树结构,所有的数据节点从左到右都是按顺序存放在同一层的叶子节点上,这就为数据的顺序查找或者范围查找提供了极大的便利,查询效率使用大O表示法为O(logN);

mysql使用B+树存取数据,相对于所有数据的顺序查找来说,磁盘IO的速度相当低下,而B+树的查找往往只需要几次的磁盘IO,效率是十分惊人的;

回到问题本身,聚集索引和非聚集索引的区别是什么?最根本的区别在于索引的顺序和表数据的顺序是否一致。。

①聚集索引:使用聚集索引的表,记录和索引保持着一致的顺序,这样只要找到索引的值就能直接从叶子节点里面获取到全部列数据;

JAVA面试被问mysql聚集索引和非聚集索引的区别?

②非聚集索引:记录和索引的顺序往往不同,可理解为索引下面的叶子节点存储的还是索引,想要获得真正的列数据,还需要再一次查询;

JAVA面试被问mysql聚集索引和非聚集索引的区别?

根据上面的描述,聚集索引常常用在重复值不多(数据库通常会自动加内置的rowID保证列成为唯一索引),长度不大的列(比如主键等),而且聚集索引十分适合于顺序查询(order by)和范围查询(between,>,<),但是不适合于频繁修改的列,和大字段的列,因为这会导致数据在磁盘上大量移动的性能消耗;

而非聚集索引更常被用于频繁更新的列,列长度比较大的场景;

有人做过形象的比喻,聚集索引就像是使用拼音查字典(比如b就是100-150页),而非聚集索引是使用部首查字典(比如弓在100页,张在200页)!

场景适用性截图如下:

JAVA面试被问mysql聚集索引和非聚集索引的区别?

在下列场景中,不应该使用索引:

1,表数据不多:表数据不多的时候,磁盘IO本来就少,加索引只会增加IO开销;

2,不常使用的列:没必要;

3,频繁更新的列:插入和删除时需要额外维护一份索引数据,会影响总的效率;