学习 SQL Server 文档(五) 索引类型及使用原则
在确定某一索引适合某一查询之后,可以自定义最适合具体情况的索引类型。索引分为:
- 聚集还是非聚集(有称聚簇)
- 唯一还是不唯一
- 单列还是多列(有称组合索引)
- 索引中的列顺序为升序还是降序
- 覆盖还是非覆盖
一. 聚集索引聚集索引确定表中数据的物理顺序。由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引,但该索引可以包含多个列(组合索引)。聚集索引对于那些经常要搜索范围值的列特别有效。当索引值唯一时,使用聚集索引查找特定的行也很有效率。注意事项定义聚集索引键时使用的列越少越好,这一点很重要。如果定义了一个大型的聚集索引键,则同一个表上定义的任何非聚集索引都将增大许多,因为非聚集索引条目包含聚集键。可考虑将聚集索引用于:
- 包含大量非重复值的列。
- 使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。
- 被连续访问的列。
- 返回大型结果集的查询。
- 经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。
- OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。
聚集索引不适用于:
- 频繁更改的列:这将导致整行移动(因为 SQL Server 必须按物理顺序保留行中的数据值)。这一点要特别注意,因为在大数据量事务处理系统中数据是易失的。
- 宽键:来自聚集索引的键值由所有非聚集索引作为查找键使用,因此存储在每个非聚集索引的叶条目内。
二. 非聚集索引非聚集索引与课本中的索引类似。数据存储在一个地方,索引存储在另一个地方,索引带有指针指向数据的存储位置。索引中的项目按索引键值的顺序存储,而表中的信息按另一种顺序存储(这可以由聚集索引规定)。如果在表中未创建聚集索引,则无法保证这些行具有任何特定的顺序。与使用书中索引的方式相似,Microsoft SQL Server 2000 在搜索数据值时,先对非聚集索引进行搜索,找到数据值在表中的位置,然后从该位置直接检索数据。这使非聚集索引成为精确匹配查询的最佳方法,因为索引包含描述查询所搜索的数据值在表中的精确位置的条目。如果基础表使用聚集索引排序,则该位置为聚集键值;否则,该位置为包含行的文件号、页号和槽号的行 ID (RID)。例如,对于在 emp_id 列上有非聚集索引的表,如要搜索其雇员 ID (emp_id),SQL Server 会在索引中查找这样一个条目,该条目精确列出匹配的 emp_id 列在表中的页和行,然后直接转到该页该行。多个非聚集索引有些书籍包含多个索引。可以为在表中查找数据时常用的每个列创建一个非聚集索引。注意事项在创建非聚集索引之前,应先了解您的数据是如何被访问的。可考虑将非聚集索引用于:
- 包含大量非重复值的列,如姓氏和名字的组合(如果聚集索引用于其它列)。如果只有很少的非重复值,如只有 1 和 0,则大多数查询将不使用索引,因为此时表扫描通常更有效。
- 不返回大型结果集的查询。
- 返回精确匹配的查询的搜索条件(WHERE 子句)中经常使用的列。
- 经常需要联接和分组的决策支持系统应用程序。应在联接和分组操作中使用的列上创建多个非聚集索引,在任何外键列上创建一个聚集索引。
- 在特定的查询中覆盖一个表中的所有列。这将完全消除对表或聚集索引的访问。
三. 唯一索引唯一索引可以确保索引列不包含重复的值。在多列唯一索引的情况下,该索引可以确保索引列中每个值组合都是唯一的。聚集索引和非聚集索引都可以是唯一的。因此,只要列中的数据是唯一的,就可以在同一个表上创建一个唯一的聚集索引和多个唯一的非聚集索引。如果必须实施唯一性以确保数据的完整性,则应在列上创建 UNIQUE 或 PRIMARY KEY 约束,而不要创建唯一索引。创建 PRIMARY KEY 或 UNIQUE 约束会在表中指定的列上自动创建唯一索引。索引的填充因子:在创建聚集索引时,表中的数据按照索引列中的值的顺序存储在数据库的数据页中。在表中插入新的数据行或更改索引列中的值时,Microsoft SQL Server 2000 可能必须重新组织表中的数据存储,以便为新行腾出空间,保持数据的有序存储。这同样适用于非聚集索引。向一个已满的索引页添加某个新行时,SQL Server 把大约一半的行移到新页中以便为新行腾出空间。这种重组称为页拆分。页拆分会降低性能并使表中的数据存储产生碎片。重建索引:在 Microsoft SQL Server 2000 中,如果要用一个步骤重新创建索引,而不想删除旧索引并重新创建同一索引,则使用 CREATE INDEX 语句的 DROP_EXISTING 子句可以提高效率。这一优点既适用于聚集索引也适用于非聚集索引。以删除旧索引然后重新创建同一索引的方式重建聚集索引,是一种昂贵的方法,因为所有二级索引都使用聚集键指向数据行。如果只是删除聚集索引然后重新创建,则会使所有非聚集索引都被删除和重新创建两次。一旦删除聚集索引并再次重建该索引,就会发生这种情形。删除聚集索引可能要花费一些时间,因为必须重建同一个表上的所有非聚集索引。
Categorized in: Database · Tagged with: Database


(