sql索引

一 .聚集索引
 
聚集索引的页级别包含了索引键,还包含数据页,因此,关于 除了键值以外聚集索引的叶级别还存放了什么的答案就是一切,也就是说,每行的所有字段都在叶级别种。
另一种说话是:数据本身也是聚集索引的一部分,聚集索引基于键值保持表中的数据有序。
SQL SERVER 中,所有的聚集索引都是唯一的,如果在创建聚集索引时没有指定UNIQUE 关键字,SQL SERVER 会在需要时通过往记录中添加一个唯一标识符(Uniqueifier)在内部保证索引的唯一性,该唯一标识符是一个4字节的值,作为附加在聚集索引键的字段添加到数据中,只有那些声明为索引键字段并拥有重复值的行才会被添加。

二 .非聚集索引

对于非聚集索引,叶级别不包含全部的数据。除了键值以外,每个叶级别(树的最低层)中的索引行包含了一个书签(bookmark),告诉SQL Server 可以在哪里找到与索引键相应的数据行。一个书签课能有两种格式。如果表上存在聚集索引,书签就是相应的数据行的聚集索引键。如果表是堆(heap)结构 ,就是没有聚集索引的情况下 ,书签就是一个行标识符 row identifier,rid ,以 文件号 页号 槽号 的格式来定位实际的行。

非聚集索引的存在与否并不影响数据分页的组织,因此每张表上并不像聚集索引那样只局限于拥有一个非聚集索引,SQL  Server 2005  每张表能够包含249 个非聚集索引 SQL Server 2008 每张表能够包含999 个非聚集索引 ,但是实际上所用到的比这个数要少的多。

三 .包含索引

索引键字段数量限制是16个,总共900个字节大小 ,包含性列只在叶级别中出现而且不以任何方式控制索引行的排序。它们的目的是使叶级别能够包含更多的信息从而更大地发挥覆盖索引(Covering index)的索引调优能力.覆盖索引是一种非聚集索引,在其叶级别就可以找到满足查询的全部信息,这样sql server就根本没有必要访问数据分页了,在一些情况下 sql serer 会悄悄的为索引添加一个包含性列。这可能发生在索引建立于分区表 也就是我今天是发的博客 O(∩_∩)O (partitioned table )上没有指定 on filegroup  或者 no partition_scheme  的情况下。

     

不论是 聚集索引,还是非聚集索引,都是用 B+树来实现的。我们在了解这两种索引之前,需要先了解B+树。如果你对B树不了解的话,建议参看以下几篇文章:

BTree,B-Tree,B+Tree,B*Tree都是什么
http://blog.csdn.net/manesking/archive/2007/02/09/1505979.aspx

B+ 树的结构图:

B+ 树的特点:

·        所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;

·        不可能在非叶子结点命中;

·        非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;

B+ 树中增加一个数据,或者删除一个数据,需要分多种情况处理,比较复杂,这里就不详述这个内容了。 

聚集索引( Clustered Index)

·        聚集索引的叶节点就是实际的数据页

·        在数据页中数据按照索引顺序存储

·        行的物理位置和行在索引中的位置是相同的

·        每个表只能有一个聚集索引

·        聚集索引的平均大小大约为表大小的 5%左右

下面是两副简单描述聚集索引的示意图: 

在聚集索引中执行下面语句的的过程:

select * from table where firstName = 'Ota'

 

一个比较抽象点的聚集索引图示:

非聚集索引 ( Unclustered Index)  

·        非聚集索引的页,不是数据,而是指向数据页的页。

·        若未指定索引类型,则默认为非聚集索引

·        叶节点页的次序和表的物理存储次序不同

·        每个表最多可以有 249个非聚集索引

·        在非聚集索引创建之前创建聚集索引(否则会引发索引重建)

在非聚集索引中执行下面语句的的过程:

select * from employee where lname = 'Green'

一个比较抽象点的非聚集索引图示:

     

      其实对于非专业的数据库操作人员来讲,例如软件开发人员,在很大程度上都搞不清楚数据库索引的一些基本知识,有些是知其一不知其二,或者是知其然不知其所以然。造成这种情况的主要原因我觉的是行业原因,有很多公司都有自己的DBA团队,他们会帮助你优化SQL,开发人员即使不懂优化问题也不大,所以开发人员对这方面也就不会下太多功夫去了解SQL优化,但如果公司没有这样的DBA呢,就只能靠程序员自己了。 最近突然想起前一阵和一朋友的聊天,当时他问我的问题是一个非常普通的问题:说说SQL聚集索引和非聚集索引的区别。

大家可能认为这个问题难度不大,认为太熟悉了,也许不会感兴趣,但你真能说清楚吗?其实要想说明白这两者的差别也不是三两句就说的清的,那天我也是觉的这问题太泛了,就随便说了其中的两个区别:

  1. 聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个,这个跟没问题没差别,一般人都知道。
  2. 聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续,这个大家也都知道。

上面的两点从大的方面讲都是讲的通的,后面我们继续探讨,举一个实际点的例子,一个学生表student,里面是学生号id,学生姓名,学生所在城市ID,学生成绩(总分)。

  • 问:如果想按姓名查询,如何做优化?
  • 答:在姓名字段上建立索引。
  • 问:建立什么类型的索引?
  • 答:建立非聚集索引。
  • 问:为什么?
  • 答:一般有范围查询的需求,可以考虑在此字段上创建聚集索引。
  • 问:学分有重复性,在学分字段上创建聚集索引能行吗? ....沉思,不能创建吗?之前的项目好像真这样做过
  • 答:应该可以吧。
  • 问:聚集索引的约束是什么?
  • 答:唯一性啊?
  • 问:既然是唯一性,那么学分字段上还能创建聚集索引吗?....再次沉思,应该可以啊,但索引的约束又怎么说呢?
  • 答:应该可以的,以前用过。

我自认为是对数据库索引知识有一定研究的,但可能是有两年没实际接触SQL的原因,一时还真想不出具有说服力的解释,朋友们看到这能解答我的问题吗?

其实上面的我们需要搞清楚以下几个问题:

第一:聚集索引的约束是唯一性,是否要求字段也是唯一的呢?

分析:如果认为是的朋友,可能是受系统默认设置的影响,一般我们指定一个表的主键,如果这个表之前没有聚集索引,同时建立主键时候没有强制指定使用非聚集索引,SQL会默认在此字段上创建一个聚集索引,而主键都是唯一的,所以理所当然的认为创建聚集索引的字段也需要唯一。

结论:聚集索引可以创建在任何一列你想创建的字段上,这是从理论上讲,实际情况并不能随便指定,否则在性能上会是恶梦。

第二:为什么聚集索引可以创建在任何一列上,如果此表没有主键约束,即有可能存在重复行数据呢?

粗一看,这还真是和聚集索引的约束相背,但实际情况真可以创建聚集索引,分析其原因是:如果未使用 UNIQUE 属性创建聚集索引,数据库引擎将向表自动添加一个四字节 uniqueifier 列。必要时,数据库引擎 将向行自动添加一个 uniqueifier 值,使每个键唯一。此列和列值供内部使用,用户不能查看或访问。

第三:是不是聚集索引就一定要比非聚集索引性能优呢?

如果想查询学分在60-90之间的学生的学分以及姓名,在学分上创建聚集索引是否是最优的呢?

答:否。既然只输出两列,我们可以在学分以及学生姓名上创建联合非聚集索引,此时的索引就形成了覆盖索引,即索引所存储的内容就是最终输出的数据,这种索引在比以学分为聚集索引做查询性能更好。

第四:在数据库中通过什么描述聚集索引与非聚集索引的?

索引是通过二叉树的形式进行描述的,我们可以这样区分聚集与非聚集索引的区别:聚集索引的叶节点就是最终的数据节点,而非聚集索引的叶节仍然是索引节点,但它有一个指向最终数据的指针。

第五:在主键是创建聚集索引的表在数据插入上为什么比主键上创建非聚集索引表速度要慢?

有了上面第四点的认识,我们分析这个问题就有把握了,在有主键的表中插入数据行,由于有主键唯一性的约束,所以需要保证插入的数据没有重复。我们来比较下主键为聚集索引和非聚集索引的查找情况:聚集索引由于索引叶节点就是数据页,所以如果想检查主键的唯一性,需要遍历所有数据节点才行,但非聚集索引不同,由于非聚集索引上已经包含了主键值,所以查找主键唯一性,只需要遍历所有的索引页就行,这比遍历所有数据行减少了不少IO消耗。这就是为什么主键上创建非聚集索引比主键上创建聚集索引在插入数据时要快的真正原因。

好了,讲这这些,不知道大家是否真的了解SQL的聚焦索引,我也是数据库新手(从使用时间上来讲也不算新了,哈哈),不专业,有什么不对的地方,希望大家批评指正,下篇我会分析一些数据库访问索引的情况,有图的情况下,也许看的更加明白。

CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
    ON <object> ( column [ ASC | DESC ] [ ,...n ] )
    [ INCLUDE ( column_name [ ,...n ] ) ]
    [ WHERE <filter_predicate> ]
    [ 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_COMPRESSION = { NONE | ROW | PAGE}
     [ ON PARTITIONS ( { <partition_number_expression> | <range> }
     [ , ...n ] ) ]
}

<filter_predicate> ::=
    <conjunct> [ AND <conjunct> ]

<conjunct> ::=
    <disjunct> | <comparison>

<disjunct> ::=
        column_name IN (constant ,...n)

<comparison> ::=
        column_name <comparison_op> constant

<comparison_op> ::=
    { IS | IS NOT | = | <> | != | > | >= | !> | < | <= | !< }

<range> ::=
<partition_number_expression> TO <partition_number_expression>


Backward Compatible Relational Index
Important   The backward compatible relational index syntax structure will be removed in a future version of SQL Server. Avoid using this syntax structure in new development work, and plan to modify applications that currently use the feature. Use the syntax structure specified in <relational_index_option> instead.

CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
    ON <object> ( column_name [ ASC | DESC ] [ ,...n ] )
    [ WITH <backward_compatible_index_option> [ ,...n ] ]
    [ ON { filegroup_name | "default" } ]

<object> ::=
{
    [ database_name. [ owner_name ] . | owner_name. ]
    table_or_view_name
}

<backward_compatible_index_option> ::=
{
    PAD_INDEX
  | FILLFACTOR = fillfactor
  | SORT_IN_TEMPDB
  | IGNORE_DUP_KEY
  | STATISTICS_NORECOMPUTE
  | DROP_EXISTING
}
       

UNIQUE

为表或视图创建唯一索引。 唯一索引不允许两行具有相同的索引键值。 视图的聚集索引必须唯一。

无论 IGNORE_DUP_KEY 是否设置为 ON,数据库引擎都不允许为已包含重复值的列创建唯一索引。 否则,数据库引擎会显示错误消息。 必须先删除重复值,然后才能为一列或多列创建唯一索引。 唯一索引中使用的列应设置为 NOT NULL,因为在创建唯一索引时,会将多个 Null 值视为重复值。

CLUSTERED

创建索引时,键值的逻辑顺序决定表中对应行的物理顺序。 聚集索引的底层(或称叶级别)包含该表的实际数据行。 一个表或视图只允许同时有一个聚集索引。

具有唯一聚集索引的视图称为索引视图。 为一个视图创建唯一聚集索引会在物理上具体化该视图。 必须先为视图创建唯一聚集索引,然后才能为该视图定义其他索引。 有关详细信息,请参阅创建索引视图

在创建任何非聚集索引之前创建聚集索引。 创建聚集索引时会重新生成表中现有的非聚集索引。

如果没有指定 CLUSTERED,则创建非聚集索引。

注意 注意

因为按照定义,聚集索引的叶级别与其数据页相同,所以创建聚集索引和使用 ON partition_scheme_name 或 ON filegroup_name 子句实际上会将表从创建该表时所在的文件组移到新的分区方案或文件组中。 对特定的文件组创建表或索引之前,应确认哪些文件组可用并且有足够的空间供索引使用。

在一些示例中,创建聚集索引可以启用以前禁用的索引。 有关详细信息,请参阅启用索引和约束禁用索引和约束

NONCLUSTERED

创建一个指定表的逻辑排序的索引。 对于非聚集索引,数据行的物理排序独立于索引排序。

无论是使用 PRIMARY KEY 和 UNIQUE 约束隐式创建索引,还是使用 CREATE INDEX 显式创建索引,每个表都最多可包含 999 个非聚集索引。

对于索引视图,只能为已定义唯一聚集索引的视图创建非聚集索引。

默认值为 NONCLUSTERED。

index_name

索引的名称。 索引名称在表或视图中必须唯一,但在数据库中不必唯一。 索引名称必须符合标识符的规则。

column

索引所基于的一列或多列。 指定两个或多个列名,可为指定列的组合值创建组合索引。 table_or_view_name 后的括号中,按排序优先级列出组合索引中要包括的列。

一个组合索引键中最多可组合 16 列。 组合索引键中的所有列必须在同一个表或视图中。 组合索引值允许的最大大小为 900 字节。

不能将大型对象 (LOB) 数据类型 ntexttextvarchar(max) nvarchar(max)varbinary(max)xmlimage 的列指定为索引的键列。 另外,即使 CREATE INDEX 语句中并未引用 ntexttextimage 列,视图定义中也不能包含这些列。

如果 CLR 用户定义类型支持二进制排序,则可以为该类型的列创建索引。 另外,对于已定义为用户定义类型列的方法调用的计算列,只要这些方法标记为确定性方法且不执行数据访问操作,便可为该计算列创建索引。 有关为 CLR 用户定义类型的列创建索引的详细信息,请参阅 CLR 用户定义类型

[ ASC | DESC ]

确定特定索引列的升序或降序排序方向。 默认值为 ASC。

INCLUDE (column [ ,...n ] )

指定要添加到非聚集索引的叶级别的非键列。 非聚集索引可以唯一,也可以不唯一。

在 INCLUDE 列表中列名不能重复,且不能同时用于键列和非键列。 如果对表定义了聚集索引,则非聚集索引始终包含聚集索引列。 有关详细信息,请参阅创建带有包含列的索引

textntextimage 之外,允许所有数据类型。 如果指定的任一非键列属于 varchar(max)nvarchar(max)varbinary(max) 数据类型,则必须脱机 (ONLINE = OFF) 创建或重新生成该索引。

精确或不精确的确定性计算列都可以是包含列。 imagentexttextvarchar(max)nvarchar(max)varbinary(max)xml 数据类型派生的计算列可以包含在非键列中,前提是允许将这些计算列数据类型作为包含列。 有关详细信息,请参阅计算列上的索引

有关创建 XML 索引的信息,请参阅 CREATE XML INDEX (Transact-SQL)

WHERE <filter_predicate>

通过指定索引中要包含哪些行来创建筛选索引。 筛选索引必须是对表的非聚集索引。 为筛选索引中的数据行创建筛选统计信息。

筛选谓词使用简单比较逻辑且不能引用计算列、UDT 列、空间数据类型列或 hierarchyID 数据类型列。 比较运算符不允许使用 NULL 文本的比较。 请改用 IS NULL 和 IS NOT NULL 运算符。

下面是一些 Production.BillOfMaterials 表筛选谓词示例:

WHERE StartDate > '20000101' AND EndDate <= '20000630'

WHERE ComponentID IN (533, 324, 753)

WHERE StartDate IN ('20000404', '20000905') AND EndDate IS NOT NULL

筛选索引不适用于 XML 索引和全文索引。 对于 UNIQUE 索引,仅选定的行必须具有唯一的索引值。 筛选索引不允许有 IGNORE_DUP_KEY 选项。

ON partition_scheme_name(column_name)

指定分区方案,该方案定义要将分区索引的分区映射到的文件组。 必须通过执行 CREATE PARTITION SCHEMEALTER PARTITION SCHEME,使数据库中存在该分区方案。 column_name 指定对已分区索引进行分区所依据的列。 该列必须与 partition_scheme_name 使用的分区函数参数的数据类型、长度和精度相匹配。 column_name 不限于索引定义中的列。 除了在对 UNIQUE 索引分区时,必须从用作唯一键的列中选择 column_name 外,还可以指定基表中的任何列。 通过此限制,数据库引擎可验证单个分区中的键值唯一性。

注意 注意

在对非唯一的聚集索引进行分区时,如果尚未指定分区依据列,则默认情况下数据库引擎将在聚集索引键列表中添加分区依据列。 在对非唯一的非聚集索引进行分区时,如果尚未指定分区依据列,则数据库引擎会添加分区依据列作为索引的非键(包含)列。

如果未指定 partition_scheme_namefilegroup 且该表已分区,则索引会与基础表使用相同分区依据列并被放入同一分区方案中。

注意 注意

您不能对 XML 索引指定分区方案。 如果基表已分区,则 XML 索引与该表使用相同的分区方案。

有关将索引分区的详细信息,请参阅已分区表和已分区索引

ON filegroup_name

为指定文件组创建指定索引。 如果未指定位置且表或视图尚未分区,则索引将与基础表或视图使用相同的文件组。 该文件组必须已存在。

ON "default"

为默认文件组创建指定索引。

在此上下文中,“default”一词不是关键字。 它是默认文件组的标识符,并且必须进行分隔(类似于 ON "default" 或 ON [default])。 如果指定了 "default",则当前会话的 QUOTED_IDENTIFIER 选项必须为 ON。 这是默认设置。 有关详细信息,请参阅 SET QUOTED_IDENTIFIER (Transact-SQL)

[ FILESTREAM_ON { filestream_filegroup_name | partition_scheme_name | "NULL" } ]

在创建聚集索引时,指定表的 FILESTREAM 数据的位置。 FILESTREAM_ON 子句用于将 FILESTREAM 数据移动到不同的 FILESTREAM 文件组或分区方案。

filestream_filegroup_name 是 FILESTREAM 文件组的名称。 该文件组必须包含一个使用 CREATE DATABASEALTER DATABASE 语句为该文件组定义的文件;否则,将引发错误。

如果表已分区,则必须包含 FILESTREAM_ON 子句并且必须指定 FILESTREAM 文件组的分区方案,且此分区方案需使用与该表分区方案相同的分区函数和分区列。 否则将引发错误。

如果该表未分区,则无法对 FILESTREAM 列分区。 该表的 FILESTREAM 数据必须存储在一个由 FILESTREAM_ON 子句指定的文件组中。

如果创建的是聚集索引且该表不包含 FILESTREAM 列,则可在 CREATE INDEX 语句中指定 FILESTREAM_ON NULL。

有关详细信息,请参阅 FILESTREAM (SQL Server)

 

<object>::=

要为其建立索引的完全限定对象或非完全限定对象。

database_name

数据库的名称。

schema_name

表或视图所属架构的名称。

table_or_view_name

要为其建立索引的表或视图的名称。

必须使用 SCHEMABINDING 定义视图,才能为视图创建索引。 必须先为视图创建唯一的聚集索引,才能为该视图创建非聚集索引。 有关索引视图的详细信息,请参阅“备注”部分。

 

<relational_index_option>::=

指定创建索引时要使用的选项。

PAD_INDEX = { ON | OFF }

指定索引填充。 默认值为 OFF。

ON

fillfactor 指定的可用空间百分比应用于索引的中间级页。

OFF 或不指定 fillfactor

考虑到中间级页上的键集,将中间级页填充到接近其容量的程度,以留出足够的空间,使之至少能够容纳索引的最大的一行。

PAD_INDEX 选项只有在指定了 FILLFACTOR 时才有用,因为 PAD_INDEX 使用由 FILLFACTOR 指定的百分比。 如果为 FILLFACTOR 指定的百分比不够大,无法容纳一行,数据库引擎将在内部覆盖该百分比以允许最小值。 中间级索引页上的行数永远都不会小于两行,无论 fillfactor 的值有多小。

在向后兼容的语法中,WITH PAD_INDEX 等效于 WITH PAD_INDEX = ON。

FILLFACTOR =fillfactor

指定一个百分比,指示在数据库引擎创建或重新生成索引的过程中,应将每个索引页面的叶级填充到什么程度。 fillfactor 必须为介于 1 至 100 之间的整数值。 如果 fillfactor 为 100,则数据库引擎将创建完全填充叶级页的索引。

FILLFACTOR 设置仅在创建或重新生成索引时应用。 数据库引擎并不会在页中动态保持指定的可用空间百分比。 若要查看填充因子设置,请使用 sys.indexes 目录视图。

重要说明 重要提示

使用低于 100 的 FILLFACTOR 值创建聚集索引会影响数据占用的存储空间量,因为数据库引擎在创建聚集索引时会重新分布数据。

有关详细信息,请参阅为索引指定填充因子

SORT_IN_TEMPDB = { ON | OFF }

指定是否在 tempdb 中存储临时排序结果。 默认值为 OFF。

ON

tempdb 中存储用于生成索引的中间排序结果。 如果 tempdb 与用户数据库不在同一组磁盘上,就可缩短创建索引所需的时间。 但是,这会增加索引生成期间所使用的磁盘空间量。

OFF

中间排序结果与索引存储在同一数据库中。

除在用户数据库中创建索引所需的空间外,tempdb 还必须有大约相同的额外空间来存储中间排序结果。 有关详细信息,请参阅 用于索引的 SORT_IN_TEMPDB 选项

在向后兼容的语法中,WITH SORT_IN_TEMPDB 等效于 WITH SORT_IN_TEMPDB = ON。

IGNORE_DUP_KEY = { ON | OFF }

指定在插入操作尝试向唯一索引插入重复键值时的错误响应。 IGNORE_DUP_KEY 选项仅适用于创建或重新生成索引后发生的插入操作。 当执行 CREATE INDEXALTER INDEXUPDATE 时,该选项无效。 默认值为 OFF。

ON

向唯一索引插入重复键值时将出现警告消息。 只有违反唯一性约束的行才会失败。

OFF

向唯一索引插入重复键值时将出现错误消息。 整个 INSERT 操作将被回滚。

对于对视图创建的索引、非唯一索引、XML 索引、空间索引以及筛选的索引,IGNORE_DUP_KEY 不能设置为 ON。

若要查看 IGNORE_DUP_KEY,请使用 sys.indexes

在向后兼容的语法中,WITH IGNORE_DUP_KEY 等效于 WITH IGNORE_DUP_KEY = ON。

STATISTICS_NORECOMPUTE = { ON | OFF}

指定是否重新计算分发统计信息。 默认值为 OFF。

ON

不会自动重新计算过时的统计信息。

OFF

启用统计信息自动更新功能。

若要恢复统计信息自动更新,请将 STATISTICS_NORECOMPUTE 设置为 OFF,或执行 UPDATE STATISTICS 但不包含 NORECOMPUTE 子句。

重要说明 重要提示

如果禁用分布统计的自动重新计算,可能会妨碍查询优化器为涉及该表的查询选取最佳执行计划。

在向后兼容的语法中,WITH STATISTICS_NORECOMPUTE 等效于 WITH STATISTICS_NORECOMPUTE = ON。

DROP_EXISTING = { ON | OFF }

指定应删除并重新生成已命名的先前存在的聚集或非聚集索引。 默认值为 OFF。

ON

删除并重新生成现有索引。 指定的索引名称必须与当前的现有索引相同;但可以修改索引定义。 例如,可以指定不同的列、排序顺序、分区方案或索引选项。

OFF

如果指定的索引名称已存在,则会显示一条错误。

使用 DROP_EXISTING 不能更改索引类型。

在向后兼容的语法中,WITH DROP_EXISTING 等效于 WITH DROP_EXISTING = ON。

ONLINE = { ON | OFF }

指定在索引操作期间基础表和关联的索引是否可用于查询和数据修改操作。 默认为 OFF。

注意 注意

在 Microsoft SQL Server 的每个版本中均不支持联机索引操作。 有关 SQL Server 的每个版本支持的功能列表,请参阅 SQL Server 2012 各个版本支持的功能

ON

在索引操作期间不持有长期表锁。 在索引操作的主要阶段,源表上只使用意向共享 (IS) 锁。 这使得能够继续对基础表和索引进行查询或更新。 操作开始时,在很短的时间内对源对象持有共享 (S) 锁。 操作结束时,如果创建非聚集索引,将在短期内获取对源的 S(共享)锁;当联机创建或删除聚集索引时,以及重新生成聚集或非聚集索引时,将在短期内获取 SCH-M(架构修改)锁。 对本地临时表创建索引时,ONLINE 不能设置为 ON。

OFF

在索引操作期间应用表锁。 创建、重新生成或删除聚集索引或者重新生成或删除非聚集索引的脱机索引操作将对表获取架构修改 (Sch-M) 锁。 这样可以防止所有用户在操作期间访问基础表。 创建非聚集索引的脱机索引操作将对表获取共享 (S) 锁。 这样可以防止更新基础表,但允许读操作(如 SELECT 语句)。

有关详细信息,请参阅联机索引操作的工作方式

可以联机创建包括全局临时表上的索引在内的索引,但下列索引例外:

  • XML 索引

  • 对局部临时表的索引。

  • 视图唯一的初始聚集索引。

  • 已禁用的聚集索引。

  • 聚集索引,前提是基础表包含 LOB 数据类型:imagentexttext 和空间类型。

有关详细信息,请参阅联机执行索引操作

ALLOW_ROW_LOCKS = { ON | OFF }

指定是否允许行锁。 默认值为 ON。

ON

在访问索引时允许使用行锁。 数据库引擎确定何时使用行锁。

OFF

不使用行锁。

ALLOW_PAGE_LOCKS = { ON | OFF }

指定是否允许使用页锁。 默认值为 ON。

ON

在访问索引时允许使用页锁。 数据库引擎确定何时使用页锁。

OFF

不使用页锁。

MAXDOP = max_degree_of_parallelism

只在索引操作期间覆盖 配置 max degree of parallelism 服务器配置选项 配置选项。 使用 MAXDOP 可以限制在执行并行计划的过程中使用的处理器数量。 最大数量为 64 个处理器。

max_degree_of_parallelism 可以是:

1

取消生成并行计划。

>1

基于当前系统工作负荷,将并行索引操作中使用的最大处理器数限制为指定数量或更少。

0(默认值)

根据当前系统工作负荷使用实际的处理器数量或更少数量的处理器。

有关详细信息,请参阅配置并行索引操作

注意 注意

并非在 Microsoft SQL Server 的每个版本中均支持并行索引操作。 有关 SQL Server 的每个版本支持的功能列表,请参阅 SQL Server 2012 各个版本支持的功能

DATA_COMPRESSION

为指定的索引、分区号或分区范围指定数据压缩选项。 选项如下所示:

NONE

不压缩索引或指定的分区。

ROW

使用行压缩来压缩索引或指定的分区。

PAGE

使用页压缩来压缩索引或指定的分区。

有关压缩的详细信息,请参阅数据压缩

ON PARTITIONS ( { <partition_number_expression> | <range> } [ ,...n] )

指定应用 DATA_COMPRESSION 设置的分区。 如果索引未分区,则 ON PARTITIONS 参数将产生错误。 如果不提供 ON PARTITIONS 子句,则 DATA_COMPRESSION 选项将应用于分区索引的所有分区。

可以按以下方式指定 <partition_number_expression>:

  • 提供一个分区号,例如:ON PARTITIONS (2)。

  • 提供若干单独分区的分区号并用逗号将它们隔开,例如:ON PARTITIONS (1, 5)。

  • 同时提供范围和单个分区,例如:ON PARTITIONS (2, 4, 6 TO 8)。

<range> 可以指定为以单词 TO 隔开的分区号,例如:ON PARTITIONS (6 TO 8)。

若要为不同分区设置不同的数据压缩类型,请多次指定 DATA_COMPRESSION 选项,例如:

 
复制
REBUILD WITH 
(
DATA_COMPRESSION = NONE ON PARTITIONS (1), 
DATA_COMPRESSION = ROW ON PARTITIONS (2, 4, 6 TO 8), 
DATA_COMPRESSION = PAGE ON PARTITIONS (3, 5)
)
原文地址:https://www.cnblogs.com/snowhumen/p/2574007.html