聚簇索引和非聚簇索引区别

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/a549654065/article/details/100128772

聚簇索引和非聚簇索引区别

MySQL的聚簇索引是指Innodb引擎的特性,MySIAM并没有,如果需要该索引,只要将索引指定为主键(primary key)就可以了。

聚集(clustered)索引,也称聚簇索引。聚簇索引并不是一种单独的索引类型,而是一种数据存储方式。Innodb引擎的聚簇索引实际上存放了B+树索引和数据行。所以由于无法同时把数据行存放在两个不同的地方,所以一个表只能有一个聚簇索引。 在Innodb引擎下,有主键时,根据主键创建聚簇索引;没有主键时,会用一个唯一且不为空的索引列做为主键,成为此表的聚簇索引,如果以上两个都不满足,那Innodb自己创建一个虚拟的聚集索引。

优点:

1.数据访问更快,因为聚簇索引将索引和数据保存在同一个B+树中,因此从聚簇索引中获取数据比非聚簇索引更快。

2.聚簇索引对于主键的排序查找和范围查找速度非常快。

缺点:

1.插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,否则将会出现页分裂,严重影响性能。因此,对于InnoDB表,我们一般都会定义一个自增的ID列为主键

2.更新主键的代价很高,因为将会导致被更新的行移动。因此,对于InnoDB表,我们一般定义主键为不可更新。

3.二级索引访问需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。


非聚集索引,也称非聚簇索引(有时也叫二级索引)。除了聚簇索引以外的索引,统称为非聚簇索引。

在聚簇索引之上创建的索引称之为辅助索引,**辅助索引访问数据总是需要二次查找。**辅助索引叶子节点存储的不再是行的物理位置,而是主键值。通过辅助索引首先找到的是主键值,再通过主键值找到数据行的数据页,再通过数据页中的Page Directory找到数据行。

Innodb辅助索引的叶子节点并不包含行记录的全部数据,叶子节点除了包含键值外,还包含了相应行数据的聚簇索引键。辅助索引的存在不影响数据在聚簇索引中的组织,所以一张表可以有多个辅助索引。

讲完了定义,下面,我们可以看一下MYSQL中MYISAM和INNODB两种引擎的索引结构。

首先看MYISAM的,因为MYISAM里并没有聚簇索引,所以MYISAM的索引都是非聚簇索引的!

首先创建表

CREATE TABLE layout_test(
	col1 int NOT NULL,
    col2 int NOT NULL,
    PRIMARY KEY(col1),
    KEY(col2)
);

数据在MyISAM中是这样分布的。在行的旁边显示了行号,从0开始递增。

[外链图片转存失败(img-HC8nzo8C-1567006464878)(mysql/7.png)]

那col2列上的索引又是怎样呢?答案是它跟其他索引没有什么区别。

[外链图片转存失败(img-NPtJatrh-1567006464879)(mysql/8.png)]


下面看InnoDB的数据分布。由于InnoDB支持聚簇索引,所以使用非常不同的方式存储同样的数据。如图所示:

[外链图片转存失败(img-L43G4nb5-1567006464880)(mysql/9.jpg)]

一眼看上去可能跟MyISAM的非聚簇索引没有什么区别。其实不然,聚簇索引的每一个叶子节点都包含了主键值、事务ID、用于事务和MVVC的回滚指针以及所有剩余列(这个例子中是col2)。


可能看完了上面,还有点混乱。再看一个例子。

[外链图片转存失败(img-jQ1dE6Kg-1567006464880)(mysql/10.jpg)]

上面的图中属于聚簇索引的只有左边的主键索引,其他的都是非聚簇索引。

InnoDB的的二级索引(辅助键索引)的叶子节点存放的是KEY字段加主键值。因此,通过二级索引查询首先查到是主键值,然后InnoDB再根据查到的主键值通过主键索引找到相应的数据块。而MyISAM的二级索引叶子节点存放的还是列值与行号的组合,叶子节点中保存的是数据的物理地址。所以可以看出MYISAM的主键索引和二级索引没有任何区别,主键索引仅仅只是一个叫做PRIMARY的唯一、非空的索引,且MYISAM引擎中可以不设主键。简单地说,聚簇索引直接能搜索叶节点的时候就能搜索到数据,而非聚簇索引搜索到叶节点还得再去根据指针找到相应的数据,显然,聚簇索引比较快。

聚簇索引和非聚簇索引的区别:

聚簇索引一个表只能有一个,非聚簇索引一个表可以有多个。

聚簇索引的叶子节点存放的是主键值和数据行,一般为表的主键(主索引),支持覆盖索引。

非聚簇索引的叶子节点存放的是主键值或指向数据行的指针,因此在使用辅助索引进行查找时,需要先查找到主键值,然后在通过主索引进行查找。

参考博客:https://www.xuejiayuan.net/blog/9b93a02df0da42b4b06074b01ef46a21

猜你喜欢

转载自blog.csdn.net/a549654065/article/details/100128772