聚簇索引与非聚簇索引的区别

一般状况下,创建索引是加快查询速度的有效手段。但索引不是万能的,靠索 引并不能实现对全部数据的快速存取。事实上,若是索引策略和数据检索需求严重不符的话,创建索引反而会下降查询性能。所以在实际使用当中,应该充分考虑到 索引的开销,包括磁盘空间的开销及处理开销(如资源竞争和加锁)。例如,若是数据频繁的更新或删加,就不宜创建索引。算法

    本文 简要讨论一下聚簇索引的特色及其与非聚簇索引的区别。
  • 创建索引:
在SQL语言中,创建聚簇索引使用CREATE INDEX语句,格式为:CREATE CLUSTER INDEX index_name ON table_name(column_name1,column_name2,...);
  • 存储特色:
  1. 汇集索引。表数据按照索引的顺序来存储的,也就是说索引项的顺序与表中记录的物理顺序一致。对于汇集索引,叶子结点即存储了真实的数据行,再也不有另外单独的数据页。 在一张表上最多只能建立一个汇集索引,由于真实数据的物理顺序只能有一种。
  2. 非汇集索引。表数据存储顺序与索引顺序无关。对于非汇集索引,叶结点包含索引字段值及指向数据页数据行的逻辑指针,其行数量与数据表行数据量一致。
    总结一下:汇集索引是一种稀疏索引,数据页上一级的索引页存储的是页指针,而不是行指针。而对于非汇集索引,则是密集索引,在数据页的上一级索引页它为每个数据行存储一条索引记录。
  • 更新表数据
一、向表中插入新数据行
    若是一张表没有汇集索引,那么它被称为“堆集”(Heap)。这样的表中的数据行没有特定的顺序,全部的新行将被添加到表的末尾位置。而创建了聚簇索引的数据表则不一样:最简单的状况下,插入操做根据索引找到对应的数据页,而后经过挪动已有的记录为新数据腾出空间,最后插入数据。若是数据页已满,则须要拆分数据页,调整索引指针(且若是表还有非汇集索引,还须要更新这些索引指向新的数据页)。而相似于自增列为汇集索引的,数据库系统可能并不拆分数据页,而只是简单的新添数据页。

二、从表中删除数据行数据库

    对删除数据行来讲:删除行将致使其下方的数据行向上移动以填充删除记录形成的空白。若是删除的行是该数据页中的最后一行,那么该数据页将被回收,相应的索 引页中的记录将被删除。对于数据的删除操做,可能致使索引页中仅有一条记录,这时,该记录可能会被移至邻近的索引页中,原索引页将被回收,即所谓的“索引 合并”。ide

 

 

 

聚簇索引肯定表中数据的物理顺序。聚簇索引相似于电话簿,后者按姓氏排列数据。因为聚簇索引规定数据在表中的物理存 储顺序,所以一个表只能包含一个聚簇索引。但该索引能够包含多个列(组合索引),就像电话簿按姓氏和名字进行组织同样。汉语字典也是聚簇索引的典型应用, 在汉语字典里,索引项是字母+声调,字典正文也是按照先字母再声调的顺序排列。

 

聚簇索引对于那些常常要搜索范围值的列特别有效。使用聚簇索引找到包含第一个值的行后,即可以确保包含后续索引值的行在物理相邻。例如,若是应用程序执行的一个查询常常检索某一日期范围内的记录,则使用 汇集索引能够迅速找到包含开始日期的行,而后检索表中全部相邻的行,直到到达结束日期。这样有助于提升此类查询的性能。一样,若是对从表中检索的数据进行排序时常常要用到某一列,则能够将该表在该列上聚簇(物理排序),避免每次查询该列时都进行排序,从而节省成本。
 

创建聚簇索引的思想

一、大多数表都应该有聚簇索引或使用分区来下降对表尾页的竞争,在一个高 事务的环境中,对最后一页的封锁严重影响系统的吞吐量。
二、在聚簇索引下,数据在物理上按顺序排在数据页上,重复值也排在一块儿,于是在那些包含范围检查 (between、<、<=、>、>=)或使用group by或orderby的查询时,一旦找到具备范围中第一个键值的行,具备后续索引值的行保证物理上毗连在一块儿而没必要进一步搜索,避免了大范围扫描,能够大 大提升查询速度。
三、在一个频繁发生插入操做的表上创建聚簇索引时,不要建在具备单调上升值的列(如IDENTITY)上,不然会常常引发封锁冲突。
四、在聚簇索引中不要包含常常修改的列,由于码值修改后,数据行必须移动到新的位置。
五、选择聚簇索引应基于where子句和链接操做的类型。
 
不知从什么角度来对比,只能说说各自的特色,但愿对你有用。
一、聚簇索引
a) 一个索引项直接对应实际数据记录的存储页,可谓“直达”
b) 主键缺省使用它
c) 索引项的排序和数据行的存储排序彻底一致,利用这一点,想修改数据的存储顺序,能够经过改变主键的方法(撤销原有主键,另找也能知足主键要求的一个字段或一组字段,重建主键)
d) 一个表只能有一个聚簇索引(理由:数据一旦存储,顺序只能有一种)

二、非聚簇索引
a) 不能“直达”,可能链式地访问多级页表后,才能定位到数据页
b) 一个表能够有多个非聚簇索引





第二种理解:

聚簇索引是对磁盘上实际数据从新组织以按指定的一个或多个列的值排序的算法。特色是存储数据的顺序和索引顺序一致。
通常状况下主键会默认建立聚簇索引,且一张表只容许存在一个聚簇索引。布局

在《数据库原理》一书中是这么解释聚簇索引和非聚簇索引的区别的:
聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针。性能

所以,MYSQL中不一样的数据存储引擎对聚簇索引的支持不一样就很好解释了。
下面,咱们能够看一下MYSQL中MYISAM和INNODB两种引擎的索引结构。spa

如原始数据为:

MyISAM引擎的数据存储方式如图:

指针

MYISAM是按列值与行号来组织索引的。它的叶子节点中保存的其实是指向存放数据的物理块的指针。
从MYISAM存储的物理文件咱们能看出,MYISAM引擎的索引文件(.MYI)和数据文件(.MYD)是相互独立的。orm

而InnoDB按聚簇索引的形式存储数据,因此它的数据布局有着很大的不一样。它存储数据的结构大体以下:

注:聚簇索引中的每一个叶子节点包含主键值、事务ID、回滚指针(rollback pointer用于事务和MVCC)和余下的列(如col2)。htm

INNODB的二级索引与主键索引有很大的不一样。InnoDB的二级索引的叶子包含主键值,而不是行指针(row pointers),这减少了移动数据或者数据页面分裂时维护二级索引的开销,由于InnoDB不须要更新索引的行指针。其结构大体以下:

排序

INNODB和MYISAM的主键索引与二级索引的对比:

InnoDB的的二级索引的叶子节点存放的是KEY字段加主键值。所以,经过二级索引查询首先查到是主键值,而后InnoDB再根据查到的主键值经过主键
索引找到相应的数据块。而MyISAM的二级索引叶子节点存放的仍是列值与行号的组合,叶子节点中保存的是数据的物理地址。因此能够看出MYISAM的主
键索引和二级索引没有任何区别,主键索引仅仅只是一个叫作PRIMARY的惟1、非空的索引,且MYISAM引擎中能够不设主键
相关文章
相关标签/搜索