从CREATE开始数据库
随约束建立的隐含索引post
当向表中添加以下两种约束之一时,就会建立隐含索引。测试
CREATE INDEX语句所作的事情与其听上去同样-用于在指定表或视图上基于声明的列建立索引:优化
CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX <index name> ON <table or view name>(<column name> [ASC|DESC][,...n]) INCLUDE (<column name> [,...n]) [ WITH [PAD_INDEX = {ON | OFF}] [[,] FILLFACTOR = <fillfactor>] [[,] IGNORE_DUR_KEY = {ON | OFF}] [[,] DROP_EXISTING = {ON | OFF}] [[,] STATISTICS_NORECOMPUTE = {ON | OFF}] [[,] SORT_IN_TEMPDB = {ON | OFF}] [[,] ONLINE = {ON | OFF}] [[,] ALLOW_ROW_LOCKS = {ON | OFF}] [[,] ALLOW_PAGE_LOCKS = {ON | OFF}] [[,] MAXDOP = <maxinum degree of parallelism> ] [ON {<filegroup> | <partition scheme name> | DEFAULT}]
CREATE INDEX语句必须随表或者视图出现,而且须要声明列所在(ON)的表。下面解释个选项的做用ui
一、ASC/DESCspa
这两个选项容许为索引选择升序和降序排列顺序。默认选项为ASC,它是升序。指针
为何须要升序和降序两个选项呢?不是反序查看索引不就好了吗?可是若是一列按升序排列,可是其余列要求按降序排列,怎么办呢?由于索引的列是存储在一块儿的,因此对一列反向查看索引也将倒转其余列的顺序。若是显示地声明某一列是升序,而另外一列是降序,那么将直接在索引的物理数据中倒转第二列-忽然间就没必要改变访问数据的方式了。code
二、INCLUDE对象
这是SQL Server2005及后续版本支持的选项。它的目的是为覆盖查询(covered queries)提供更好的支持。blog
当包含(INCLUDE)列而不是将列放在ON列表上时,SQL Server仅仅在索引的叶级上添加它们。由于在索引叶级上的每一行对应于一个数据行,因此所作的事情在本质上是将更多的原始数据包含在索引的叶级上。这样作有一个好处,由于SQL Server在有了它实际须要的内容就中止工做。SQL Server在遍历索引时没有继续访问实际的数据行就找到所需的全部数据,那么就没必要再到达数据行。经过在索引中包含特定的列,能够在叶级“覆盖”利用该特定索引的查询,从而节省了与使用索引指针到达数据页相关的I/O。实际是,好比你为一个日期列建立索引,可是INCLUDE一个订单ID列。那么查找某日期的订单ID,就没必要再到实际数据行了,由于在索引中就有了所需的数据。可是注意不要滥用该选项,当包含列时,将增长索引页的叶级的大小。这意味着每页中的行数将更少,所以须要更多的I/O来查看相同数量的行。结果多是,加快了一个查询的同时可能减慢了其余的查询。要考虑对系统各个部分的影响,而不是仅仅考虑某个时候正在使用的特定查询。
三、WITH
WITH很是简单-它只是告诉SQL Server将要提供一个或者多个跟在后面的选项。
四、PAD_INDEX
该选项肯定了第一次建立索引时,索引的非叶级页将有多满(用百分比表示)。不用在PAD_INDEX中声明百分比,由于将使用后面的FILLTACTOR选项指定的百分比。设置不带有FILLFACTOR选项的PAD_INDEX=ON将是没有意义的。
五、FILLFACTOR
当SQL Server第一次建立索引时,默认状况下将尽量地将页填满,仅留两个记录的控件,能够将FILLTACTOE设置为在0-100之间的任意值。一旦索引构造完成,这个数字将表示页相对满的程度的百分比。可是在进行页拆分时,数据将仍然在两页之间对半分布-除了按期重建索引外,不能不断地控制填充百分比。
当须要调整页密度的时候,使用FILLTACTOR须要从如下几方面考虑:
六、IGNORE_DUP_KEY
IGNORE_DUP_KEY选项几乎是一种回避系统的方法。简而言之,它使得惟一约束与其应有的操做方式有些不一样。
一般,惟一约束(或惟一索引)不容许任何种类的重复-若是事务尝试基于定义为惟一的列建立重复值,那么事务将被回滚而且拒绝。然而,一旦设置了IGNORE_DUP_KEY选项,就将获得混合的行为。仍然接收错误信息,可是错误将仅仅是一种警告-记录仍然没有被插入。
从IGNORE_DUP_KEY的角度看,不能会事务进行回滚(错误还是警告错误,而不是关键错误),但重复的行将被拒绝。
一句话,这个东西的态度是,重复行彻底没问题,可是你要有一个该值的行存在就OK了(插入时,重复行被忽略,仍是所有都不容许插入)。
当你建立惟一索引时,你能够指定IGNORE_DUP_KEY选项,所以本文最开始建立惟一索引的选项能够是:
CREATE UNIQUE NONCLUSTERED INDEX AK_Product_Name ON Production.Product ( [Name] ) WITH ( IGNORE_DUP_KEY = OFF );
IGNORE_DUP_KEY这个名字容易让人误会。惟一索引存在时重复的值永远不会被忽略。更准确的说,惟一索引中永远不容许存在重复键。这个选项的做用仅仅是在多列插入时有用。
好比,你有两个表,表A和表B,有着彻底相同的结构。你可能提交以下语句给SQL Server。
INSERT INTO TableA SELECT * FROM TableB;
SQL Server会尝试将全部表B中的数据插入表A。但若是由于惟一索引拒绝表B中含有和表A相同的数据插入A怎么办?你是但愿仅仅重复数据插入不成功,仍是整个INSERT语句不成功?
这个取决于你设定的IGNORE_DUP_KEY参数,当你建立惟一索引时,经过设置设个参数能够设定当插入不成功时怎么办,设置IGNORE_DUP_KEY的两种参数解释以下:
IGNORE_DUP_KEY=OFF
整个INSERT语句都不会成功并弹出错误提示,这也是默认设置。
IGNORE_DUP_KEY=OFF
只有那些具备重复键的行不成功,其它全部的行会成功。并弹出警告信息。
IGNORE_DUP_KEY 选项仅仅影响插入语句。而不会被UPDATE,CREATE INDEX,ALTER INDEX所影响。这个选项也能够在设置主键和惟一约束时进行设置。
七、DROP_EXISTING
若是指定DROP_EXISTING选项,那么若是以前已经存在同名索引将在构造新索引以前被删除。当和群集索引一块儿使用该选项时,这个选项比简单删除并从新建立现有的索引更加有效。若是从新建立与现有索引彻底匹配的索引,那么SQL Server知道它不须要涉及非群集索引,然而为了适应不一样的行位置,显式删除和建立将致使从新构建全部非群集索引两次。若是使用DROP_EXISTING改变索引的结构,那么NCI只被从新构建一次,而不是两次。
八、STATISTICS_NORECOMPUTE
默认状况下,SQL Server试图自动化在表和索引上更新统计信息的过程。经过选择该选项,表示将由本身手动负责更新统计信息。为了关闭这个选项,须要运行UPDATESTATISTICS命令,但不使用NORECOMPUTE。
强烈建议不要使用该选项,由于查询优化器使用索引上的统计信息来指出索引对于给定的查询有多大用处。随着表中数据大量增多或减小,以及列特定值改变。索引上的统计信息会不断变化。基于这两点,能够知道不更新统计信息则查询优化器将基于过期的信息运行查询,打开自动统计信息功能意味着统计信息将周期地更新(多长时间更新一次取决于对表更新的本质和频繁程度)。相反关闭自动更新统计信息意味着信息会过期,或者须要设定计划手动运行UPDATE STATISTICS。
九、SORT_IN_TEMPDB
只有在tempdb存储在与包含新索引的数据库物理上分离的驱动器上时,该选项才有意义。为何?
当SQL Server创建索引时,它必须执行多个读操做以处理各类索引构造步骤。
一、遍历全部的数据,构建对应于实际数据每一行的叶行。相似于实际数据和最后的索引,这些内容进入用于临时存储的页。这些中间页不是最终的索引页,而是每次排序缓冲器已满时临时存储的位置。
二、经过这些中间页单独运行,以将他们合并到最终叶级页。
三、当填充叶级页时,构建非叶级页。
若是没有使用SORT_IN_TEMPDB选项,那么中间页将被写入在其中存储数据库的相同物理文件中。这意味着实际数据的读操做必须与构建过程的写操做竞争。这两种状况形成磁头须要移动到一个不一样的位置(读和写)。结果是磁头常常地来回移动-这会花费时间。
另外一方面,若是使用SORT_IN_TEMPDB,那么中间页将被写入tempdb中,而不是数据库本身的文件。若是它们在单独的物理驱动器上,这意味着在索引构建的读和写操做之间没有竞争。可是要牢记,只有在tempdb位于与数据库文件分离的独立物理驱动器上,这才会有效。不然,只是名义上发生改变,而I/O竞争仍然是问题。
若是要使用SORT_IN_TEMPDB,那么确保在tempdb中有用于支持大文件的足够空间。
十、ONLINE
若是将这个选项设置为ON,那么它将强制表对于通常的访问保持有效,而且不建立任何阻止用户使用索引和/表的锁。默认状况下,全索引操做将得到所需的锁(最终获得表锁),以便对表进行彻底和有效的访问,然而,反作用是这将会阻止用户(这是矛盾的:一方面可能正在创建索引以使数据库更为有用,可是同时又使表变得不可用)。
十一、ALLOW ROW/PAGE LOCKS
这里的ALLOW设置用于肯定索引是否容许行锁和页锁。
十二、MAXDOP
该选项用于为构建索引覆盖关于最大并行度的系统设置。并行度是指将有多少个进程用于一个数据库操做。有一个称为最大并行度的系统设置,容许限制每一个操做中的处理器数。索引建立的MAXDOP选项容许将并行度设置为高于或者低于基本系统设置。只要合适就行。
1三、ON
SQL Server容许经过使用ON选项将数据和索引单独存放。这样作有如下优势:
下面简单补充下XML索引的概念。
XML索引是SQL Server2005新增功能。
除了IGNORE_DUP_KEY和ONLINE以外,XML的建立语法支持前面的CREATE语句中所看到的全部相同选项。
在SQL Server中,能够再类型为XML的列上建立索引。这样作的主要要求以下。
一、主XML索引
在XML索引上建立的第一个索引必须声明为"主索引"。当建立主索引时,SQL Server建立一个新的群集索引,这个群集索引将基表的群集索引和来自任何指定的XML节点的数据组合在一块儿。
二、辅助XML索引
相似于指向群集索引的群集键的非群集索引,辅助XML索引以很类似的方法指向主XML索引。一旦建立了主XML索引,就只能在XML列上建立多达248个以上的XML索引。
ALTER INDEX命令在其用来作什么方面多少有些欺骗性。截止到如今,ALTER命令老是与修改对象的定义有关。例如ALTER表以添加或禁用约束和列。ALTER INDEX是不一样的-该命令与维护有关,而与结构彻底不相干。若是需修改索引的组成,那么只能DROP而后CREATE索引,或者用DROP_EXISTING=ON选项CREATE并使用索引。
ALTER INDEX的语法相似于下面这样:
ALTER INDEX {<name of index> | ALL} ON<table or view name> { REBUILD [[ WITH ( [PAD_INDEX = {ON | OFF}] | [[,] FILLFACTOR = <fillfactor> | [[,] SORT_IN_TEMPDB = { ON | OFF }] | [[,] IGNORE_DUP_KEY = { ON | OFF }] | [[,] STATISTICS_NORECOMPUTE = { ON | OFF }] | [[,] ONLINE = { ON| OFF }] | [[,] ALLOW_ROW_LOCKS = { ON | OFF }] | [[,] ALLOW_PAGE_LOCKS = { ON | OFF }] | [[,] MAXDOP = <max degree of parallelism> )] |[ PARTITION = <partition number> [ WITH (< partition rebuild index option> [,...N])]]] | DISABLE | REORGANIZE [ PARTITION = <partition number> ] [ WITH (LOB_COMPACTION = { ON | OFF })] | SET ([ ALLOW_ROW_LOCKS = { ON | OFF} ] | [[,] ALLOW_PAGE_LOCKS = { ON | OFF } ] | [[,] IGNORE_DUP_KEY = { ON | OFF } ] | [[,] STATISTICS_NORECOMPUTE = { ON | OFF }] ) }[;]
其中一些选项与CREATE INDEX命令相同,所以这里将略过对这些选项的从新定义。除此以外,至关多的ALTER特定选项都是细节性的,且与处理碎片之类的事情有关。下面解释下参数
一、索引名
若是想维护一个特定的索引能够指定该索引,或者使用ALL代表想要维护与指定的表相关联的全部索引。
二、表名或视图名
要在其上维护的特定对象(表或视图)的名称。注意,必须是一个特定的表(能够给它提供一个列表,而后说“请处理全部这些!”)。
三、REBULD
若是使用该选项运行ALTER INDEX,那么将彻底丢弃旧的索引并从新生成新的索引。结果是真正优化的索引,其中全部叶级和非叶级的页都按照定义进行了从新构建。若是是群集索引,那么也会从新组织物理数据。
默认状况下,页将被从新组织为差两行满。和CREATE TABLE语法同样,能够将FILLFACTOR设置为0~100以前的任何值。该值是在数据库完成从新组织后页被填满的程度(以百分比表示)。但在进行页拆分时,数据将被对半分部在两个页上-除了按期重建索引外,不得不断控制填充的百分比。
要当心使用该选项,一旦开始REBUILD,在完成索引重建钱,正在使用的索引实际上就没有了。依赖该索引的全部查询可能会变得异常慢。对于这类事情,首先须要在离线系统上测试,以了解整个过程将花多少时间。而后,计划在非高峰时段运行。
四、DISABLE
该选项名副其实,只是方式有些过激。若是该命令的所有做用只是为了让索引离线,直至您决定了进一步要作什么,则它是不错的选择,但它实际会把索引标记为不可用,一旦禁用了某个索引,在从新激活以前,必须重建索引(不是从新组织,而是重建)。
若是对表禁用了群集索引,那么也会禁用表。数据仍会保留,但在重建群集索引钱,不能被全部索引(由于他们都依赖群集索引)访问。
五、REORGANIZE
若是从新组织索引,就获得了比彻底重建索引稍逊一点的彻底优化,但这种方法能够联机进行(用户仍能使用索引)。
稍逊一点指的是什么?实际上是REORGANIZE只在索引的叶级起做用,而不触及非叶级。这意味着未得到彻底优化。可是,对于大部分的索引而言,那不是真正产生碎片的地方。
若是不断地从新分析状况和添加索引,那么也不要忘记删除索引。记住在插入索引上的系统开销。
删除索引的语法以下:
DROP INDEX <table or view name>.<index name>
这样就能够删除索引了。