一、使用聚集索引
一个表智能有一个聚集索引,当创建此索引时,还会发生以下事件。
- 会重新整理表数据
- 会创建新索引页
- 数据库内的所有非聚集索引会被重建
结果,会存在许多磁盘I/O操作,会大量使用系统和内存资源。因此,如果计划创建聚集索引,要确保有足够的自由空间,至少等于表中数据量的1.5倍。
通常情况下,在主键上创建聚集索引。当创建聚集索引时,正在索引的值应是唯一的。
二、使用非聚集索引
如果有聚集索引,则书签指示聚集索引键,否则,书签是实际的行定位器。
当创建非聚集索引时,SQL Server创建所需要的索引页,但不会重新整理表数据,并且不会删除表的其他索引。每一个表可拥有多大249个非聚集索引。
三、确定应当索引哪些列
选择表和列进行索引的原则
可以索引的表或列 | 不要索引的表或列 |
有许多行的表 | 几乎没有行的表 |
在查询中经常用到的列 | 查询中很少用到的列 |
有宽范围的值,并且在一个典型查询中行极有可能被选择的列 | 有宽范围的值,但在一个典型的查询中行不太可能被选择的列 |
用于聚合函数的列 | 列的字节数大 |
用于GROUP BY 查询的列 | 有许多修改,但很少有实际查询的表 |
用于ORDER BY 查询的列 | |
用于表联接的列 |
使用聚集和非聚集索引的原则
使用聚集索引的列 | 使用非聚集索引的列 |
被大范围的搜索的主键,如帐号 | 为顺序标识符的主键,如标识列 |
返回大结果集的查询 | 返回小结果集的查询 |
在许多查询中用到的列 | 在聚合行数中用到的列 |
强选择性的列 | 外键 |
用于ORDER BY 或 GROUP BY 查询的列 | |
用于表联接的列 |
四、索引计算列和视图
对计算列和视图的索引需要将结果存储在数据库中以供将来引用。对于计算列,计算列值,然后用于建立存储在索引中的键。对于视图,通过对视图创建聚集索引来存储结果集。在这两种情况下,只有当引用这些结果的所有连接都可以生成完全相同的结果集时,存储结果才有效,这对于如何在计算列和视图上创建索引设定了特定限制。
必须使用特定的SET选项来建立引用这些结果的连接,这些选项必须具有同样的设置。必须如下设置选项:
- ANSI_NULLS 必须设置为ON。
- ANSI_PADDING 必须设置为ON。
- ANSI_WARNINGS 必须设置为ON。
- ARITHABORT 必须设置为ON。
- CONCAT_NULL_YIELDS_NULL 必须设置为ON。
- QUOTED_IDENTIFIER 必须设置为ON。
- NUMERIC_ROUNDABORT必须设置为OFF。
此外,所有引用该视图的操作都必须使用完全相同的算法来生成视图结果集,包括:
- 生成初始化结果集或用于计算初始键的CREATE INDEX 语句。
- 对用于生成视图结果集或用于计算键的数据产生影响的任何后续 INSERT、UPDATE 或 DELETE 语句。
- 查询优化器必须为其确定该索引视图是否有用的所有查询。
五、查看索引属性
EXEC sp_statistics table
六、创建索引
关系索引的语法:
CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
ON <object> ( column [ ASC | DESC ] [ ,...n ] )
[ INCLUDE ( column_name [ ,...n ] ) ]
[ WITH ( <relational_index_option> [ ,...n] ) ]
[ ON { partition_scheme_name ( column_name)
| filegroup_name
| default
}
]
[ FILESTREAM_ON { filestream_filegroup_name
| partition_scheme_name | "NULL" } ]
[;]
<object> ::=
{ [ database_name. [schema_name ] . | schema_name. ]
table_or_view_name }
<relational_index_option> ::=
{ PAD_INDEX = { ON | OFF }
| FILLFACTOR = fillfactor
| SORT_IN_TEMPDB = { ON | OFF }
| IGNORE_DUP_KEY = { ON | OFF }
| STATISTICS_NORECOMPUTE = { ON | OFF }
| DROP_EXISTING = { ON | OFF }
| ONLINE = { ON | OFF }
| ALLOW_ROW_LOCKS = { ON | OFF }
| ALLOW_PAGE_LOCKS = {ON | OFF }
| MAXDOP = max_degree_of_parallelism }
| DATA_COMPRESSTION = { NONE | ROW | PAGE }
[ ON PARTITIONS ( { <partition_number_expression> | <range> }
[ ,...n ] ) ]
}
<filter_predicate> ::=
<conjunct> [ AND <conjunct> ]
<conjunct> ::=
<disjunct> | <comparison>
<disjunct> ::=
column_name IN (constant ,...)
<comparison> ::=
column_name <comparison_op> constant
<comparison_op> ::=
{ IS |IS NOT | = | <> | != | > | >= | !> | < | <= | !< }
<range> ::=
<partition_number_expression> TO <partition_number_expression>