http://blog.csdn.net/wobuwei/article/details/4486105、http://jingyan.baidu.com/article/e73e26c0f1e82d24acb6a75d.html、http://blog.csdn.net/fredrickhu/article/details/6227876
、https://zhidao.baidu.com/question/362506868036124932.html/、http://www.cnblogs.com/aspnethot/articles/1504082.html、http://www.2cto.com/database/201411/351106.html-阅读地址
索引:
首先,建立索引会在磁盘上建立索引文件,索引的数据都存储在索引文件中,所以进行索引检索的时候,会产生磁盘I/O消耗
一、深入浅出理解索引结构
实际上,您可以把索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。下面,我们举例来说明一下聚集索引和非聚集索引的区别:
其实,我们的汉语字典的正文本身就是一个聚集索引。比如,我们要查“安”字,就会很自然地翻开字典的前几页,因为“安”的拼音是“an”,而按照拼音排序汉字的字典是以英文字母“a”开头并以“z”结尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”开头的部分仍然找不到这个字,那么就说明您的字典中没有这个字;同样的,如果查“张”字,那您也会将您的字典翻到最后部分,因为“张”的拼音是“zhang”。也就是说,字典的正文部分本身就是一个目录,您不需要再去查其他目录来找到您需要找的内容。我们把这种正文内容本身就是一种按照一定规则排列的目录称为“聚集索引”。
如果您认识某个字,您可以快速地从自动中查到这个字。但您也可能会遇到您不认识的字,不知道它的发音,这时候,您就不能按照刚才的方法找到您要查的字,而需要去根据“偏旁部首”查到您要找的字,然后根据这个字后的页码直接翻到某页来找到您要找的字。但您结合“部首目录”和“检字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“张”字,我们可以看到在查部首之后的检字表中“张”的页码是672页,检字表中“张”的上面是“驰”字,但页码却是63页,“张”的下面是“弩”字,页面是390页。很显然,这些字并不是真正的分别位于“张”字的上下方,现在您看到的连续的“驰、张、弩”三字实际上就是他们在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我们可以通过这种方式来找到您所需要的字,但它需要两个过程,先找到目录中的结果,然后再翻到您所需要的页码。我们把这种目录纯粹是目录,正文纯粹是正文的排序方式称为“非聚集索引”。
通过以上例子,我们可以理解到什么是“聚集索引”和“非聚集索引”。进一步引申一下,我们可以很容易的理解:每个表只能有一个聚集索引,因为目录只能按照一种方法进行排序。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
索引实际上是一个键值对,也属于表结构的一部分,类似map,不过map是无序的,又不是map。
将一个字段建立索引之后会将这个字段以键值对的形式存入数据库中,其key就是该所为的索引列,value就是该所为索引列的字段值。
索引是有序的,聚集索引会向List数组一样,将从第一个开始的元素给予序号0,后面递增1.
聚集索引是:将数据在物理上排序,比如,图书馆的的书,从编号1开始按数字,1,2,3,4,5这样一直排列下来,这里的 1,2,3,4,5就可以建立聚集索引,检索的时候假设你检索 >4的数据就很快。
非聚集是索引是:将数据在逻辑上排序(逻辑排序实际上可以理解为目录结构)。比如图书馆的书,按照语音 将中文的放到 A区,将英文放在B区,然后又按照图书的类目,比如 文学类 放在 B曲区的 1号货架,历史图书放在B区的2号货架,这样逻辑上的排序是非聚集索引。
非聚集索引与聚集索引:
非聚集索引:数据存在一个地方(这个地方并不是指表中数据),索引存在另一个地方。索引通过其值value指针来指向数据行。
聚集索引:数据与索引存在了一个地方,在查找的时候通过索引key就可以直接找到其值value,此value就是数据,不是指针。
一个非常形象的比喻:假设有一个字典,非聚集索引就是通过偏旁或者拼音才能查找到字,而聚集索引就是可以直接找到所在字的那一页查找到字。
对比:非聚集索引对比聚集索引,少了个中转节点,因此聚集索引在查找上回避非聚集索引要快,但是非聚集索引在插入与更新上要比聚集索引快。
规则:聚集索引在一个表中只能有一个,一般是默认主键为聚集索引,(在大多数时候,主键上设置聚集索引是一种资源浪费,因为通常用户是不知道一行数据的主键ID的,通常是通过name来查找的。)
若建立多个聚集索引,那么在性能上将会是一个噩梦,非聚集索引可以建立多个(也就是复合索引),但不要建立太多。
注意:使用复合聚集索引列进行where查询的时候一样要注意索引的先后顺序,起始列判定在前(网上没有起始列的解释,我认为所为起始聚合索引列就是进行排序的列,因为一张表只能有一个聚集索引进行物理排序),复合聚集索引列判定在后,这样会提高查询速度。
注意事项
定义聚集索引键时使用的列越少越好。
1、包含大量非重复值的列。
2、使用下列运算符返回一个范围值的查询:BETWEEN、>、>=、< 和 <=。
3、被连续访问的列。
4、返回大型结果集的查询。
5、经常被使用联接或 GROUP BY 子句的查询访问的列;一般来说,这些是外键列。对 ORDER BY 或 GROUP BY 子句中指定的列进行索引,可以使 SQL Server 不必对数据进行排序,因为这些行已经排序。这样可以提高查询性能。
6、OLTP 类型的应用程序,这些程序要求进行非常快速的单行查找(一般通过主键)。应在主键上创建聚集索引。
二、何时使用聚集索引或非聚集索引
下面的表总结了何时使用聚集索引或非聚集索引(很重要):
动作描述 | 使用聚集索引 | 使用非聚集索引 |
列经常被分组排序 | 应 | 应 |
返回某范围内的数据 | 应 | 不应 |
一个或极少不同值 | 不应 | 不应 |
小数目的不同值 | 应 | 不应 |
大数目的不同值 | 不应 | 应 |
频繁更新的列 | 不应 | 应 |
外键列 | 应 | 应 |
主键列 | 应 | 应 |
频繁修改索引列 | 不应 | 应 |
事实上,我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如:返回某范围内的数据一项。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行物理排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可;而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容。
物理排序:可以理解为字典的a-z排序,1-10排序,时间的从早到晚排序,都是物理排序
逻辑排序:可以理解为目录分类排序。