SQL Server索引 - 汇集索引、非汇集索引、非汇集惟一索引 <第八篇>

汇集索引、非汇集索引、非汇集惟一索引

  咱们都知道创建适当的索引可以提升查询速度,优化查询。先说明一下,不管是汇集索引仍是非汇集索引都是B树结构数据库

  •   汇集索引默认与主键相匹配,在设置主键时,SQL Server会默认在主键列建立汇集索引。可是能够手动更改成在任意一个列建立汇集索引,而后在另外一个字段或多个字段上定义主键。这时主键将会被做为一个惟一的非汇集索引(惟一索引)被建立。经过指定NONCLUSTERED关键字就能够作到。
    CREATE TABLE MyTableKeyExample
    {
      Column1 int IDENTITY  KEY NONCLUSTERED,
      Column2 int 
    }
  •   汇集索引实际上装载了SQL Server的数据记录行,汇集索引的叶级就是数据行,因此到达了汇集索引的叶级就到达了数据。
  •   为表声明主键或惟一约束时,SQL Server会自动建立与之对应的惟一索引。
  •   汇集索引的列最好就是自增的,由于根据区段-页的理论,若是汇集索引列是自增的,那么添加数据的时候,所见是放在索引的最后,不会发生由中间插入的状况,这样就不会引发页拆分。而若是索引列不是自增的,添加数据的时候,还要按顺序找到该条记录的位置,而且插入,若是插入比较频繁,还可能会常常引发页拆分。
  •   汇集索引的最佳数据类型,smallint、int、bigint、datetme。
  •   最好避免组合汇集索引。

  索引(index)是除了表以外的另外一个重要的、用户定义的存储在数据库里的数据结构。当根据索引码的值搜索数据时,索引提供了对数据的快速访问。事实上,没有索引数据库也可以根据SELECT语句经过表扫描成功地检索到结果,可是随着表变得愈来愈大,使用“适当”的索引的效果就愈来愈明显。但若是使用索引时不认真考虑其实现过程,索引反而有可能会下降数据库的工做性能。建立主键时会自动建立汇集索引,除非当前表中已经含有了汇集索引或是建立主键时指定了NONCLUSTERED关键字。数据结构

  汇集索引、非汇集索引、非汇集惟一索引:post

  SqlServer提供了两种索引:汇集索引和非汇集索引。汇集的做用就是将某一列(或是多列)的物理顺序改变为和逻辑顺序相一致。性能

  汇集索引(CLUSTERED)与非汇集索引(NONCLUSTERED)的区别:学习

  其实,咱们的汉语字典的正文自己就是一个汇集索引(按照拼音的英文字母排序) 好比,咱们要查“安”字 ,就会很天然地翻开字典的前几页,由于“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字 母“a”开头并以“z”结尾的,那么“安”字就天然地排在字典的前部。若是您翻完了全部以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;一样的,若是查“张”字,那您也会将您的 字典翻到最后部分,由于“张”的拼音是“zhang”。也就是说,字典的正文部分自己就是一个目录,您不须要再去查其余目录来找到您须要找的内容。咱们把这种正文内容自己就是一种按照必定规则排列的目录称为“汇集索引”。 这也是为何一张表只能 够有一个汇集索引的缘由。由于一张表只可以按一种方式排序。 其中汇集索引的叶级节点就是数据。你能够理解为有不少列火车,按照火车头索引(排序),火车头后面跟着的就是数据。
  若是您认识某个字,您能够快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而须要去根据“偏旁部首”查到您要找的字,而后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并非真正的正文的排序方法,好比您查“张”字,咱们能够看到在查部首以后的检字表中“张” 的页码是672页,检字表中“张”的上面是“驰”字,但页码倒是63页,“张”的下面是 “弩”字,页面390页。很显然,这些字并非真正的分别位于“张”字的上下方,如今您看到的连续的“驰、张、弩” 三字实际上就是他们在非汇集索引中的排序,是字典正文中的字在非汇集索引中的映射。咱们能够经过这种方式来找到您所须要的字,但它须要两个过程,先找到目录中的结果,而后再翻到您所须要的页码。咱们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非汇集索引”。优化

  实际上若是表上有汇集索引,则非汇集索引中存储着汇集索引的引用,而后经过利用汇集索引来获取数据。所以这就是为何返回少许数据的时候使用非汇集索引的性能较好,而返回大量的数据的时候使用非汇集索引还不如直接全表扫描来得快。而若是表上没有汇集索引的时候,则引用行号。spa

  非汇集索引须要额外的空间进行存储,按照被索引列进行汇集索引,并在B树的叶子节点包含指向非汇集索引所在表的指针。非汇集索引也是B树结构,另一个单独的B树。指针

  惟一索引:code

   当主键建立时若是不设置为汇集索引,那么就必定是惟一的非汇集索引。实际上,惟一索引,故名思议就是它要求该列上的值是惟一的。对象

  汇集索引列能够重复,非汇集索引列也能够重复。这就是为何要有惟一这个东东了。声明惟一索引的语法很简单,只是多了个UNIQUE关键字。

  CREATE UNIQUE NONCLUSTERED INDEX [AK_Product_Name] ON Production.Product ( [Name] );

  惟一索引有不少限制和特性。下面详细学习下惟一索引。

  为表声明主键或惟一约束时,SQL Server会自动建立与之对应的惟一索引。定义一个惟一约束时,SQL Server会自动建立一个与之同名的惟一索引,要删除索引必须先删除约束。但删除约束,删除约束也会致使与之关联的索引被删除,也就是说,不能删除惟一索引,要删除索引只有删除惟一约束这个办法。

  惟一索引依赖于惟一约束,删除惟一索引必须删除惟一约束。另外SQL Server又在创建惟一约束时又默认创建惟一索引。

  总结起来就是:惟一索引与惟一约束始终一同存在。

  由于定义一个主键或是定义约束会致使索引被建立,因此你必须在约束定义时就给出必要的索引信息,所以上面ALTER TABLE语句中包含了”CLUSTERED”关键字。

ALTER TABLE Production.Product ADD CONSTRAINT PK_Product_ProductID PRIMARY KEY 
CLUSTERED ( ProductID );

   若是惟一索引或约束所约束的列在当前的表中已经含有了重复值,那么建立索引会失败。而当惟一索引建立成功后,全部违反这个约束的INSERT、UPDATE语句都会失败。

消息 2601,级别 14,状态 1,第 1 行 
不能在具备惟一索引 'AK_Product_Name' 的对象 
'Production.Product' 中插入重复键的行。 
语句已终止。 

  惟一约束和惟一索引并无显著的区别。建立独立的惟一索引和使用惟一约束对于数据的验证方式并没有区别。查询优化器也不会区分惟一索引是由约束建立仍是手工建立。然而以数据完整性为目标的话,最好建立约束,这使得对应的索引的目标一目了然。

  过滤惟一索引,当咱们须要既容许多个NULL值,又不容许重复的时候,可使用这个:

  CREATE UNIQUE NONCLUSTERED INDEX xx on 
  ProductDemo(<索引列>)  --指定索引列
  where <索引列>!=null)  --过滤条件

  对于用以上语法建立的惟一索引,插入时,只有当惟一索引列不为NULL的时候才检测重复。换句话说,以上表的索引列容许多个NULL值。

相关文章
相关标签/搜索