MSSQL聚集索引與非技術索引設計指南

来源:互联网 发布:个人工作日记软件 编辑:程序博客网 时间:2024/06/02 08:06

-->Title:Generating test data
-->Author:wufeng4552
-->Date :2009-09-25 09:41:15

(一)聚集索引设计指南

聚集索引基于数据行的键值在表内排序和存储这些数据行.每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储.

定义聚集索引来实现下列功能:

1:可用于经常使用的查询

提供高度唯一性.
注意:
创建 PRIMARY KEY 约束时,将在列上自动创建唯一索引.

默认情况下,此索引是聚集索引,但是在创建约束时,可以指定创建非聚集索引.

2:可用于范围查询

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

**查询注意事项 **

在创建聚集索引之前,应先了解数据是如何被访问的,考虑对具有以下特点的查询使用聚集索引:

(1)使用运算符(如 BETWEEN、>、>=、 < 和 <=)返回一系列值。

使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行物理相邻.

例如,如果某个查询在一系列销售订单号间检索记录,SalesOrderNumber 列的聚集索引可快速定位包含起始销售订单号的行,然后检索表中所有连续的行,直到检索到最后的销售订单号.

(2)返回大型结果集。

使用 JOIN 子句;一般情况下,使用该子句的是外键列.

(3)使用 ORDER BY 或 GROUP BY 子句.

在 ORDER BY 或 GROUP BY 子句中指定的列的索引,可以使数据库引擎不必对数据进行排序,因为这些行已经排序.这样可以提高查询性能.

**列注意事项**

一般情况下,定义聚集索引键时使用的列越少越好.考虑具有下列一个或多个属性的列:

唯一或包含许多不重复的值

(1)唯一或包含许多不重复的值

例如,雇员 ID 唯一地标识雇员.

EmployeeID 列的聚集索引或 PRIMARY KEY 约束将改善基于雇员 ID 号搜索雇员信息的查询的性能.

另外,可对 LastName、FirstName、MiddleName 列创建聚集索引,

因为经常以这种方式分组和查询雇员记录,而且这些列的组合还可提供高区分度.

(2)按顺序被访问

(3)经常用于对表中检索到的数据进行排序。
按该列对表进行聚集(即物理排序)是一个好方法,它可以在每次查询该列时节省排序操作的成本.

**聚集索引不适用于具有下列属性的列:**

(1)频繁更改的列
这将导致整行移动,因为数据库引擎必须按物理顺序保留行中的数据值.

这一点要特别注意,因为在大容量事务处理系统中数据通常是可变的.

(2)宽键

宽键是若干列或若干大型列的组合.

所有非聚集索引将聚集索引中的键值用作查找键.

为同一表定义的任何非聚集索引都将增大许多,这是因为非聚集索引项包含聚集键,同时也包含为此非聚集索引定义的键列.

(二)非聚集索引设计指南

非聚集索引包含索引键值和指向表数据存储位置的行定位器

可以对表或索引视图创建多个非聚集索引.通常,设计非聚集索引是为改善经常使用的、没有建立聚集索引的查询的性能.

与使用书中索引的方式相似,查询优化器在搜索数据值时,先搜索非聚集索引以找到数据值在表中的位置,然后直接从该位置检索数据.

这使非聚集索引成为完全匹配查询的最佳选择,因为索引包含说明查询所搜索的数据值在表中的精确位置的项.

例如,为了从 HumanResources.Employee 表中查询向特定经理负责的所有雇员,查询优化器可能使用非聚集索引 IX_Employee_ManagerID,它以 ManagerID 作为其键列.查询优化器能快速找出索引中与指定 ManagerID 匹配的所有项.

每个索引项都指向表或聚集索引中准确的页和行,其中可以找到相应的数据.

在查询优化器在索引中找到所有项之后,它可以直接转到准确的页和行进行数据检索.

**数据库注意事项 **

(1)更新要求较低但包含大量数据的数据库或表可以从许多非聚集索引中获益从而改善查询性能.

    与全表非聚集索引相比,考虑为定义完善的数据子集创建筛选索引可以提高查询性能、降低索引存储开销并减少索引维护开销.

(2)决策支持系统应用程序和主要包含只读数据的数据库可以从许多非聚集索引中获益.

    查询优化器具有更多可供选择的索引用来确定最快的访问方法,并且数据库的低更新特征意味着索引维护不会降低性能.

(3) 联机事务处理应用程序和包含大量更新表的数据库应避免使用过多的索引.此外,索引应该是窄的,即列越少越好.
    对表编制大量索引会影响 INSERT、UPDATE、DELETE 和 MERGE 语句的性能,因为当表中的数据更改时,所有索引都须进行适当的调整.  

**查询注意事项 **

   在创建非聚集索引之前,应先了解访问数据的方式.考虑对具有以下属性的查询使用非聚集索引:

(1)使用 JOIN 或 GROUP BY 子句.
   应为联接和分组操作中所涉及的列创建多个非聚集索引,为任何外键列创建一个聚集索引.

(2)不返回大型结果集的查询.
   创建筛选索引以覆盖从大型表中返回定义完善的行子集的查询.

(3)包含经常包含在查询的搜索条件(例如返回完全匹配的 WHERE 子句)中的列.

**列注意事项 **

考虑具有以下一个或多个属性的列:

(1)覆盖查询.
当索引包含查询中的所有列时,性能可以提升.查询优化器可以找到索引内的所有列值;

不会访问表或聚集索引数据,这样就减少了磁盘 I/O 操作。使用具有包含列的索引来添加覆盖列,而不是创建宽索引键.

如果表有聚集索引,则该聚集索引中定义的列将自动追加到表上每个非聚集索引的末端.

这可以生成覆盖查询,而不用在非聚集索引定义中指定聚集索引列.

例如:如果一个表在 C 列上有聚集索引,则 B 和 A 列的非聚集索引将具有其自己的键值列 B、A 和 C.

(2)大量非重复值

如姓氏和名字的组合(前提是聚集索引被用于其他列)。
如果只有很少的非重复值,例如仅有 1 和 0,则大多数查询将不使用索引,因为此时表扫描通常更有效.

对于这种类型的数据,应考虑对仅出现在少数行中的非重复值创建筛选索引。

例如,如果大部分值都是 0,则查询优化器可以对包含 1 的数据行使用筛选查询。

 

原创粉丝点击