而存储引擎不能管理两份同样的数据,所以聚簇索引在同一张数据表中只能存在一个,其他的索引只能是非聚簇索引,也就是二级索引。数据表的如果有指定primary key,那么InnoDB就会把primary key作为聚簇索引来存储,如果没有,则会取第一个not null,unique的索引作为聚簇索引,unique的索引也不存在的话,InnoDB就会自行的,隐式的指定一个row ID列作为聚簇索引存储,但这个row ID不会被用户管理。
聚簇索引一些重要的优点:
1. 在有聚簇索引的数据表中,使用聚簇索引进行查询的时候,因为索引和数据聚集在同一个B-tree中,能够直接从索引获取到数据行,比非聚簇索引的性能要好。
2. 反之在没有聚簇索引的数据表中,因为不能通过unique的值去聚集数据,所以需要通过非聚簇索引查询数据的物理地址或者全表扫描来获取数据,这样每一行数据可能都会导致一次磁盘I/O。
在提升性能的同时,聚簇索引也存在着缺点:
1. 更新聚簇索引的代价会很大,因为需要将数据行和主键进行重排,移动到新的位置,并且二级索引可能也需要更新。
2. 聚簇索引的插入速度严重依赖插入顺序,严格的升序主键是性能最好的方式,但如果主键是乱序的插入,例如用uuid作为主键,当主键值需要插入到某一页已经写满的page中,存储引擎就需要将page分裂成两个页面来容纳数据,这一个 页分裂(page split) *** 作,page split会使得数据表占用更多的磁盘空间。
3. 通过二级索引获取需要两次索引查找,因为二级索引保存的是聚簇索引的主键,而不是指向数据的逻辑指针,所以获取主键后需要再进行一次搜索才能获取数据。
聚簇索引和二级索引的数据分布方式不同,在MyISAM和InnoDB的数据文件组织方式中也有体现。
MyISAM的数据由3个文件组成:1. .frm(表结构描述文件) ,2. .MYD(数据行文件) ,3. .MYI(索引文件) 。
InnoDB则有2个文件:1. .frm(表结构描述文件) ,2. .MYD(数据行文件和索引信息) 。
MyISAM引擎没有使用索引和数据的聚集的分布方式,所以主键和其他索引的是没有区别,就都存储在索引文件中。
InnoDB的锁机制是使用索引来实现,表现的等级为行级锁,而MyISAM则是表级锁,这也跟数据分布方式有关。InnoDB的主键索引与数据紧凑的聚集在一起,并且包含了事务ID,用于事务MVCC的回滚指针,而MyISAM则是数据与索引分离,无法实现如此细粒度的锁。
1. InnoDB暂时不能由用户选定索引作为聚簇索引,InnoDB有自己的聚簇索引选取规则,所以在创建表的时候最好设置一个与业务无关的主键id作为聚簇索引,这样修改二级索引和数据的时候,无需移动数据位置,提升性能。
2. 聚簇索引的主键id不要使用uuid,uuid会使得数据的插入添加额外的页分裂 *** 作,降低性能,最好使用单调自增的id。
一、含义不同:
聚簇索引(Clustered Index)并不是一种单独的索引类型,而是一种数据存储方式。当表有了聚簇索引的时候,表的数据行都存放在索引树的叶子页中。
非聚簇索引(NoClustered Index),又叫二级索引。二级索引的叶子节点中保存的不是指向行的物理指针,而是行的主键值。
二、应用不同:
在《数据库原理》里面,对聚簇索引的解释是:聚簇索引的顺序就是数据的物理存储顺序,而对非聚簇索引的解释是:索引顺序与数据物理排列顺序无关。正式因为如此,所以一个表最多只能有一个聚簇索引。
在SQL Server中,索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。
扩展资料:
因为聚簇和非聚簇索引本质上是数据存储方式,需要依赖于载体,即以InnoDB引起来讲解聚簇索引,以MyISAM来讲解非聚簇索引。下述讲解的图都引用自《高性能MySQL》。
它的每个聚簇索引的叶子节点都包含主键值、事务ID、回滚指针(用于事务和MVCC)以及余下的列。从物理文件也可以看出 InnoDB的数据文件只有数据结构文件.frm和数据文件.ibd 其中.ibd中存放的是数据和索引信息 是存放在一起的。
参考资料来源:百度百科-聚簇索引
存储特点的区别:
聚集索引。表数据按照索引的顺序来存储的,也就是说索引项的顺序与表中记录的物理顺序一致。对于聚集索引,叶子结点即存储了真实的数据行,不再有另外单独的数据页。 在一张表上最多只能创建一个聚集索引,因为真实数据的物理顺序只能有一种。
非聚集索引。表数据存储顺序与索引顺序无关。对于非聚集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,其行数量与数据表行数据量一致。
总结一下:聚集索引是一种稀疏索引,数据页上一级的索引页存储的是页指针,而不是行指针。而对于非聚集索引,则是密集索引,在数据页的上一级索引页它为每一个数据行存储一条索引记录。
更新表数据
1、向表中插入新数据行
如果一张表没有聚集索引,那么它被称为 “堆集”(Heap)。这样的表中的数据行没有特定的顺序,所有的新行将被添加到表的末尾位置。
而建立了聚簇索引的数据表则不同:最简单的情况下,插入 *** 作根据索引找到对应的数据页,然后通过挪动已有的记录为新数据腾出空间,最后插入数据。如果数据页已满,则需要拆分数据页,调整索引指针(且如果表还有非聚集索引,还需要更新这些索引指向新的数据页)。而类似于自增列为聚集索引的,数据库系统可能并不拆分数据页,而只是简单的新添数据页。
2、从表中删除数据行
对删除数据行来说:删除行将导致其下方的数据行向上移动以填充删除记录造成的空白。如果删除的行是该数据页中的最后一行,那么该数据页将被回收,相应的索引页中的记录将被删除。对于数据的删除 *** 作,可能导致索引页中仅有一条记录,这时,该记录可能会被移至邻近的索引页中,原索引页将被回收,即所谓的“索引合并”。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)