聚集索引:三级阶梯SQL Server索引
通过大卫·杜兰特,2013/01/25(第一次出版:2011/06/22)
该系列
本文是楼梯系列的一部分:SQL Server的阶梯索引
索引数据库设计的基础,告诉开发人员使用数据库设计者的意图。 不幸的是索引时往往是后加上的性能问题出现。 终于在这里是一个简单的系列文章,应该让任何数据库专业迅速“加速”
前面的水平在这个楼梯概述了非聚集索引的索引一般和特别。 结论用以下关于SQL Server关键概念索引。 当一个请求到达您的数据库,一个SELECT语句或一个INSERT、UPDATE或DELETE语句,SQL Server只有三种可能的方法来访问数据表中引用的声明:
- 访问非聚集索引,避免访问表。 这只可能在索引中包含的所有数据查询这个表所要求的
- 使用搜索键(s)来访问索引,然后使用所选的书签(s)来访问表的单个行。
- 忽略了索引和搜索请求的表行。
这个水平首先关注的第三选择上面的列表; 搜索表。 反过来,这将导致我们的讨论集群索引; 一个被提及的话题,但没有涵盖,在2级
示例数据库
尽管我们已经讨论了在一级sample数据库,值得重复。 在整个楼梯,我们将使用示例来说明概念。 这些例子是基于微软的AdventureWorks示例数据库。 我们专注于销售订单。 五表将给我们一个良好的事务性和非事务性数据;客户,销售人员,产品,SalesOrderHeader,SalesOrderDetail。 为了保持专注,我们使用列的一个子集。 因为AdventureWorks规范化,销售人员信息分解成三个表:销售人员,员工和联系。
整个楼梯我们使用以下两个术语,指一行订单互换:“行项目”和“订单细节”。 前者是更常见的业务术语; 后者的名字出现在一个AdventureWorks表。
聚集索引
我们先问以下问题:有多少工作需要找到表中的一行(s)如果不使用非聚集索引? 搜索请求的行表意味着扫描一个无序表中每一行吗? 永久或SQL Server序列表的行,以便它可以快速访问他们的搜索键,就像快速访问非聚集索引的搜索键的条目吗? 答案取决于你是否指示SQL Server上创建一个聚集索引表。
与非聚集索引是一个单独的对象,占据自己的空间,聚集索引和表是一样的。 通过创建聚集索引,您指示SQL Server排序表的行索引键序列,在未来保持序列数据的修改。 即将到来的水平会看看生成的内部数据结构来完成这个。 但是现在,想到一个聚集索引排序表。 鉴于连续索引键值,SQL Server可以快速访问这一行; 并且可以通过表的行顺序进行。
出于演示的目的,我们创建两个我们的示例表的副本,SalesOrderDetail; 一个没有索引,一个聚集索引。 关于索引的键列,我们的设计师做出同样的选择AdventureWorks数据库:SalesOrderID/SalesOrderDetailID。 清单1中的代码的副本SalesOrderDetail表。 我们可以随时重新运行这段代码,我们希望从一个“白纸”开始。
了解基本的聚集索引
聚集索引键可以由你选择的任何列; 它不需要基于主键。 在我们的例子中,最重要的是,最左侧列的关键是一个外键,SalesOrderID价值。 因此,销售订单的所有行项目中连续出现SalesOrderDetail表。
记住这些额外的点对SQL Server集群索引:
- 由于聚集索引的条目表的行,没有收藏价值在集群索引条目。 当SQL Server已经在一行,它不需要一个信息,告诉它在哪里找到这一行。
- 聚集索引总是覆盖查询。 自指数和同一个表,表的每一列的索引。
- 桌子上有一个聚集索引不影响你选择创建非聚集索引表。
- 选择聚集索引键列(s)
-
可以有最多每个表一个聚集索引。 一个表的行可以在只有一个序列。 你需要决定什么序列,如果有的话,最好为每个表; 如果可能的话,创建聚集索引表变得充满了之前的数据。 做这个决定时,请记住,测序不仅意味着订购,这也意味着分组; 在分组由销售订单行项目。
这就是为什么的设计者AdventureWorks数据库的选择SalesOrderDetailID在SalesOrderID的序列SalesOrderDetail表; 行项目的自然顺序。
例如,如果一个用户请求一个订单的行项目,他们通常会要求所有订单的行项目。 看一个典型的销售订单的形式告诉我们,订单的打印副本总是包括所有行项目。 它的本质是销售订单业务集群由销售订单行项目。 可能会有偶尔的请求从仓库想看产品而非销售订单行项目; 但大多数的请求; 如来自销售人员或客户,或程序,打印发票,或查询,计算每个订单的总价值; 需要任何销售订单的所有行项目。用户需求,然而,不确定什么是最好的聚集索引。 本系列以后的水平将覆盖的内部索引; 因为某些内部方面的聚集索引列的索引也会影响你的选择。
-
堆
如果没有聚集索引表,该表称为堆。 每个表都是一堆或一个聚集索引。 所以,尽管我们经常状态的每个索引分为两种类型,集群或非聚集; 同样重要的是要注意,每个表分成两个类型; 它是一个聚集索引或一堆。 开发人员经常说一个表“有”或“没有”一个聚集索引,但它是更有意义的说表”是”或“不是”一个聚集索引。
只有一种方法为SQL Server来搜索一个堆在寻找行(不含非聚集索引的使用),这是开始在表中的第一行并通过表进行,直到所有的行已经阅读。 没有一个序列,没有搜索键,没有办法快速导航到特定的行。
比较一个聚集索引和一堆
聚集索引的性能评价和一堆,清单1的两个副本SalesOrderDetail表。 一份是堆版,另一方面,我们创建在原始表的聚集索引(SalesOrderID,SalesOrderDetailID)。 表都没有任何非聚集索引。
我们将运行相同的三个查询每个版本的表; 一个检索一行,另一个检索单个订单,所有行和检索单个产品的所有行。 我们现在每个执行的SQL和结果表中所示。
-
结论
聚集索引是一个排序表的序列是由您创建索引时,指定由SQL Server和维护。 该表中的任意行快速访问给定键值。 任何一组行,在索引键序列,也很快访问给定的范围键。
每个表只能有一个聚集索引。 的决定应该是聚集索引的列索引键列是最重要的决定,你会让任何表。
在我们的四级我们将把我们的重点从逻辑到物理,介绍页面和区段,并检查指标的物理结构。