索引初探(三)
由于前一篇写的有点匆忙很多地方不是很简单,这一片再描述一些概念和细节。
首先,我们都知道在数据库中的存储分为两种结构,一是堆;二是B树。堆的数据是没有排序也就没有结构性可言,我们可以简单理解为没有索引的表数据就是以堆的形式存在的。与之相对的,索引都是B树的形式存储,这样的话索引中数据是有序排列的。
其次,索引的结构上篇也是讲了,我们这里再根据非聚集索引的结构来对比一下聚集索引。
如图(官方提供的非聚集索引的结构图):
我们不难看出,上面红色标注的是非聚集索引,下面是聚集索引或者堆。由这个图来分析:
1.非聚集索引与聚集索引一样都是B树结构。
2.非聚集索引的叶子节点不是数据页,这样非聚集索引的叶子节点只包含键值和定位符(定位符,存在两种可能,如果表中有了聚集索引那么定位符就是个直接指向数据所在行的物理指针,如果有聚集索引,那么就是一个指向索引的聚集键)
3.与聚集索引不同,非聚集索引本身并不会改变数据页的存储模式。
本篇的重点:非聚集索引
非聚集索引包含了索引键列,包含列和书签。书签的值根据所在表是堆还是聚集索引既可以是RID也可以是聚集索引键,我们用两个图对比看一下一目了然。
上图显示的是非聚集索引在对上的实际结构,可以发现除了索引键值外,就是“RID”就是指向数据页的指针。
上图是非聚集索引在聚集索引上的结构,可以发现除去索引键值外,就是聚集索引键,查询数据时继续到索引中去寻找数据。
那么非聚集索引的优点:
1、因为在SQL Server中一页只是8K,页面空间有限,所以一行所包含的列数越少,它能保存的行就越多。非聚集索引通常不包含表中所有的列,它一般只包含非常少数的列。因此,一个页上将能包含比表行(所有的列)更多行的非聚集索引。
2、非聚集索引的另一个好处是,它有一个独立于数据表的结构,所以可以被放置在不同的文件组,使用不同的I/O路径,这意味着SQL Server可以并行访问索引和表,使查找更快速。
3、与聚集索引不同的时,一个表中可以有多个非聚集索引增加查询覆盖和交叉等等可以提高查询速度。
通过对聚集和非聚集索引的描述大概了解两种索引的基本结构和优缺点,下面根据其他人总结的什么情况下建立何种索引的一个常规方式:
使用聚集索引 使用非聚集索引
外键列 应 应
主键列 应 应
列经常被分组排序 应 应
返回某范围内的数据 应 不应
小数目的不同值 应 不应
大数目的不同值 不应 应
频繁更新的列 不应 应
频繁修改索引列 不应 应
一个或极少不同值 不应 应
总结:
通过对索引的介绍和测试,我们发现索引能大幅提高查询的效率,但是同样相应的维护成本和性能消耗也是非常大的,这需要我们根据实际情况进行合理的设计。 当一个查询被传到数据引擎时,SQL Server可以通过三种路径获取数据来满足这个查询。
- 不需要访问表仅需要访问索引本身,这种情况必须是索引覆盖了请求所包含的列
- 使用索引键值去访问非聚集索引,然后使用书签访问非聚集索引所在表
- 全表扫描来获取数据
了解这些基础概念接下来我们将从实际应用中去解决如何优化、如何合理化使用索引。