浅谈聚集索引 & 非聚集索引

聚集索引

聚集索引表记录的排列顺序和索引的排列顺序一致,数据行的物理顺序与列值(一般是主键那一列)的逻辑顺序相同,所以查询效率快,只要找到第一个索引值记录,其余就连续性的记录在物理也一样连续存放。

一个表中只能拥有一个聚集索引。

优点是查询快。

缺点是修改慢。因为为了保证表中记录的物理和索引顺序一致,在记录插入的时候,会对数据页重新排序。

-- 添加聚集索引
create clustered index CLU_ABC on abc(A);

-- 删除聚集索引
drop index abc.CLU_ABC;
  • 其中,CLU_ABC 为聚集索引的名字,abc(A) 为表 abc 的 A 列

非聚集索引

该索引中索引的逻辑顺序与磁盘上的物理存储顺序不同,一个表中可以拥有多个非聚集索引

非聚集索引层次多,不会造成数据重排。

非聚集索引又可以分为普通索引、唯一索引、全文索引

-- 添加非聚集索引
create nonclustered index NONCLU_ABC on abc(A);

二者区别

二者的各根本区别是:表记录的排列顺序和索引的排列顺序是否一致

用一个例子来形容聚集索引和非聚集索引的区别就是:聚集索引就好像用新华字典的汉字的拼音首字母去查询汉字所在页,而非聚集索引就好像你用汉字的偏旁部首去查询一个汉字(偏旁部首的顺序跟汉字实际存储的顺序不一致)。

  • 聚集索引的叶子节点就是对应的数据节点,可以直接获取到某一行对应的全部列的信息;
  • 非聚集索引的叶子节点仍然是索引节点,只是有一个指针指向对应的数据块。在索引没有覆盖到对应的列时候需要进行二次查询。
  • 因此在查询方面,聚集索引的速度更优。

总结:

动作描述使用聚集索引使用非聚集索引
列经常被分组排序
返回某范围内的数据不应
一个或极少不同值(其他几乎都相同)不应不应
小数目的不同值不应
大数目的不同值不应
频繁更新的列不应
外键列
主键列
频繁修改索引列不应

有以下几个问题:

  1. 聚集索引的约束是唯一性,是否要求字段也是唯一的呢?

    不要求唯一!

    一般认为是唯一的,可能是受系统默认设置的影响,一般我们指定一个表的主键,如果这个表之前没有聚集索引,同时建立主键时候没有强制指定使用非聚集索引,SQL会默认在主键上创建一个聚集索引,而主键都是唯一的,所以理所当然的认为创建聚集索引的字段也需要唯一。

    聚集索引可以创建在任何一列字段上,这是从理论上讲,实际情况并不能随便指定,否则在性能上会是恶梦。

  2. 为什么聚集索引可以创建在任何一列上,如果此表没有主键约束,即,有可能存在重复行数据呢?

    如果未使用 UNIQUE 属性创建聚集索引,数据库引擎将向表自动添加一个四字节 uniqueifier 列。必要时,数据库引擎将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。

  3. 在主键是创建聚集索引的表,在数据插入上为什么比在主键上创建非聚集索引表速度要慢?

    在有主键的表中插入数据行,由于有主键唯一性的约束,所以需要保证插入的数据没有重复。

    聚集索引由于索引叶节点就是数据页,所以如果想检查主键的唯一性,需要遍历所有数据节点才行,

    而非聚集索引上已经包含了主键值,所以查找主键唯一性,只需要遍历所有的索引页就行,这比遍历所有数据行减少了不少IO消耗。

测试

假如现在有这么一张表

children

agename
11hory
25casia
37amili
49ferry

这个时候插入一条数据:

insert into children values('6','kiven');

此时再次查询为下表所示:

agename
11hory
25casia
37amili
49ferry
56kiven

添加聚集索引:

create clustered index CLU_CHIL on children(age);

再查询数据显示为如下表,此时发现表的顺序发生了变化,此时的排序按age字段的递增排序:

agename
11hory
25casia
36kiven
47amili
59ferry

删除聚集索引,会发现表的顺序不会发生改变:

drop index children.CLU_CHIL;

接着添加非聚集索引,添加新的记录:

create nonclustered index NONCLU_CHIL on children(age);
insert into children values('4','mari');

查看表顺序,如下表,并没有影响表的顺序:

agename
11hory
25casia
36kiven
47amili
59ferry
64mari
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值