很多人对索引都没有一个清晰的认识,对于聚集索引和非聚集索引之间的区别也不是很清楚。如果有人问我索引是什么,我觉得这个问题有点大,很难在一篇文章里解释清楚。所以我决定尝试写这一系列文章,用一个简单的,可以理解的方法解释索引,尽管网上关于索引的文章有一箩筐那么多。
简单来说,索引帮助数据库引擎使用最小的资源,最高效的找到需要的数据。通过唯一列索引可以保证数据的连贯性,当索引不一定要建在唯一列上。在忙碌的系统里,通过增加并发操作,可以提高性能。在一个表上建立的各个索引可以满足不同用户的请求,但这也是个头疼的问题。索引保存在不同的页,就像数据存在不同的地方,SQL Server要保证它们的一致性。对表的任何INSERT,UPDATE,DELETE操作,对应的索引页会执行相同的操作。索引帮助我们提高获取数据的性能,但对DML操作却是个麻烦。在DELETE和UPDATE里,索引会帮助数据库引擎找到需要修改的记录。一个表要建多少个索引并没有诀窍(thrumb rule)。如果你要更好的读性能,你可以创建更多的索引,如果你要更好DML操作性能,请保持最小数量的索引。
SQL Server支持2类索引:
- 聚集索引(Clustered Index:CI)
- 非聚集索引(Non Clustered Index:NCI)
让我们用现实生活中的例子来理解这2类索引。假设你的邻居到你家,问你“Woody Tu”的电话号码。在这种情况下,电话本目录就是个聚集索引。你打开电话本目录,跳过3/4的页,假定他的名字应该出现在目录的最后一部分。在前后翻过几页后,你找到了列有“Woody Tu”名字的页。现在你就可以把号码告诉你的邻居了。看看这里发生了什么?当你找到了列有“Woody Tu”名字的页时,你就有了你邻居(客户端)需要的信息。
我们再看另一个情况,你的邻居到你家,问你“Woody Tu”的电子邮件地址,而你并不记得。在这个情况下,电话本目录会扮演非聚集索引的角色。你打开电话本目录,跳过3/4的页,假定他的名字应该出现在目录的最后一部分。在前后翻过几页后,你找到了列有“Woody Tu”名字的页。现在你可以打电话给“Woody Tu”,问下他的电子邮件地址是多少。挂下电话后,你可以把他的电子邮件地址交给你的邻居。看看这里发生了什么?当你找到了列有“Woody Tu”名字的页时,你并没有邻居(客户端)需要的信息。你需要去做一个额外操作(打电话)来获得邻居(客户端)需要的信息。在SQL Server里,这个额外操作被称为书签/RID查找(Bookmark or RID Lookup,注:RID,堆的行标识符(FileID:PageID:SlotNumber))。
希望这个介绍可以让你对聚集索引和非聚集索引有了感性的认识。在接下来的文章里,我们会讨论聚集索引和非聚集索引的更多细节。