SQLServer索引结构及其使用(一)

SQLServer索引结构及其使用(一),第1张

SQLServer索引结构及其使用(一),第2张

首先,用简单的术语理解索引结构

实际上,您可以将索引理解为一种特殊的目录。微软的SQL SERVER提供了两种索引:聚集索引(也叫聚集索引、聚集索引)和非聚集索引(也叫非聚集索引、非聚集索引)。下面,我们来举例说明聚集索引和非聚集索引的区别:
其实我们的汉语词典的正文本身就是聚集索引。比如我们要查“安”这个字,自然会翻开字典的前几页,因为“安”的拼音是“an”,按照拼音排序的汉字字典是以英文字母“a”开头,以“z”结尾,所以“安”这个字自然排在字典的最前面。如果看完所有以“A”开头的部分都找不到这个词,说明你的字典里没有这个词;同样,如果你查“张”这个字,你也会把字典翻到最后一部分,因为“张”的拼音是“张”。换句话说,字典的主体本身就是一个目录,所以你不需要查找其他目录来找到你需要的内容。我们把这种文本内容本身称为按照一定规则排列的目录“聚簇索引”。
如果你知道一个单词,你可以在自动系统中快速查找。但是,你也可能遇到一个不认识的单词,不知道它的发音。这时候你按照刚才的方法是找不到你要找的单词的。而是需要根据“偏旁”找到你要找的字,然后根据这个字后面的页码直接翻到一页,找到你要找的字。而部首目录和查词表相结合找到的词的排序,并不是真正的文本排序方法。比如查“张”这个字,我们可以看到部首查完之后的查词表中“张”的页码是672页,“池”这个字在查词表的上面,但是页码是63页,页码在“张”这个字的下面。显然,这几个字并没有真正分别位于“张”字的顶端和底端。你现在看到的连续词“迟、张、弩”其实就是它们在非聚集索引中的排序,是词典正文中的词在非聚集索引中的映射。这样我们就可以找到你需要的单词,但是需要两个过程,首先在目录中找到结果,然后翻到你需要的页码。我们把这种目录称为纯目录,把文本的排序方法称为纯文本的“非聚集索引”。
通过上面的例子,我们可以了解什么是“聚集索引”和“非聚集索引”。进一步,我们很容易理解,每个表只能有一个聚集索引,因为目录只能用一种方法排序。

第二,何时使用聚集索引或非聚集索引

下表总结了何时使用聚集索引或非聚集索引(这一点很重要):

使用聚集索引的操作说明使用非聚集索引的列通常按组排序。应该返回某个范围内的数据。应该返回一个或几个不同的值。应该使用少量不同的值。应该使用大量不同的值。应该经常更新的列不应该是外键列应该是主键列应该经常修改。索引列不应
事实上,我们可以通过前面的聚集索引和非聚集索引定义的例子来理解上表。例如,返回某个范围内的一项数据。例如,您的一个表有一个时间列,您只需在该列中设置聚集索引。当你查询2004年1月1日到2004年10月1日的所有数据时,速度会非常快,因为你的字典的文本是按日期排序的,聚簇索引只需要找到所有要检索数据的开始和结束数据。与非聚集索引不同,必须先查找目录中每项数据对应的页码,然后根据页码查找具体内容。

第三,结合实际,谈谈指标使用的误区。

理论的目的是应用。虽然我们刚刚列出了什么时候应该使用聚集索引或者非聚集索引,但是在实际操作中,上述规则很容易被忽略或者不能根据实际情况进行综合分析。下面我们就根据实践中遇到的实际问题来谈谈指数使用的误区,让大家掌握指数建立的方法。

1.我认为主键是聚集索引
的想法是极其错误的,是对聚集索引的浪费。尽管默认情况下SQL SERVER在主键上构建聚集索引。
通常我们在每个表中设置一个ID列来区分每一条数据,这个ID列是自动递增的,步长为1。在我们的办公自动化示例中,列Gid就是这种情况。此时,如果我们将此列设置为主键,SQL SERVER会将此列默认为聚集索引。这个是有好处的,就是你的数据在数据库里可以按ID物理排序,但我觉得没多大意义。
显然,聚集索引的优势是显而易见的,每个表中只能有一个聚集索引的规则,这使得聚集索引更加珍贵。
从我们前面讲的聚集索引的定义可以看出,使用聚集索引的好处是可以根据查询需求快速缩小查询范围,避免全表扫描。在实际应用中,由于身份证号是自动生成的,我们不知道每条记录的身份证号,所以在实际中我们很难使用身份证号进行查询。这使得将ID号用作聚集索引的主键是一种资源浪费。其次,将不同ID号的字段作为聚集索引,不符合“大数有不同值时不应建立聚集索引”的规则。当然,这种情况只有在用户经常修改记录内容,尤其是索引项时才会有负面影响,对查询速度没有影响。
在办公自动化系统中,无论是系统首页显示的需要用户签收的文档、会议,还是用户的文件查询,没有字段“日期”和用户自己的“用户名”是无法进行数据查询的。
通常,办公自动化的主页会显示每个用户尚未签名的文档或会议。虽然我们的where语句只能限制当前用户没有签收的情况,但是如果你的系统建立时间很长,数据量很大,那么每个用户每次打开首页,扫描整个表的意义不大。大多数用户在一个月前就已经浏览过这些文件,这只会增加数据库的开销。实际上,当用户打开系统主页时,数据库只能查询用户近三个月未阅读的文件,表扫描可以通过“日期”字段进行限制,提高查询速度。如果你的办公自动化系统已经建立了2年,你的主页的显示速度理论上会比原来的速度快8倍甚至更多。
这里之所以提到“理论上”这个词,是因为如果你的聚集索引仍然盲目地建立在ID作为主键上,那么你的查询速度就没有那么高,即使你的索引(非聚集索引)建立在字段“date”上。我们来看看1000万条数据(3个月25万条数据)情况下各种查询的速度表现:

(1)主键上只建立聚集索引,不划分时间段:

Select GID,fariqi,neibu胡勇,title from tgongwen
时间:128470毫秒(即128秒)

(2)在主键上建立聚集索引,在fariq上建立非聚集索引:

从原文中选择gid,fariqi,neibuyonghu,title

其中Fariqi > DateAdd (day,-90,getDate ())
持续时间:53763毫秒(54秒)

(3)在日期列上建立聚集索引(fariqi):

从原文中选择gid,fariqi,neibuyonghu,title

其中Fariqi > DateAdd (day,-90,getDate ())
持续时间:2423毫秒(2秒)

虽然每个语句提取250,000条数据,但各种情况下的差异是巨大的,尤其是当聚集索引构建在日期列中时。事实上,如果你的数据库真的有1000万的容量,在ID列上设置主键,就像上面第一种和第二种情况一样,会导致网页超时,根本无法显示。这也是我放弃ID列作为聚集索引的最重要因素。上述速度可通过添加以下内容获得:

声明@d日期时间

Set @d=getdate()
并添加:

select[语句执行时间(毫秒)] = datediff(毫秒,@ d,getdate ())
2。只要建立了索引,就可以显著提高查询速度
。事实上,我们可以发现,在上面的例子中,第二条和第三条语句完全相同,用于索引的字段也相同;唯一不同的是,前者在fariqi字段上建立非聚集索引,后者在该字段上建立聚集索引,但查询速度相差很大。所以单纯索引任何字段都不能提高查询速度。
从建表的语句中我们可以看到,在这个1000万数据的表中,fariqi字段有5003条不同的记录。在这个领域建立一个聚合索引是完美的。现实中,我们每天都会发送几个文档,这些文档的日期都是相同的,这完全符合构建聚集索引所要求的“既不是绝大多数也不是只有少数是相同的”的规则。从这个角度来看,我们建立一个“合适的”聚集索引来提高查询速度是非常重要的。

3.将所有需要提高查询速度的字段添加到聚簇索引中以提高查询速度
如上所述,日期和用户自己的用户名是数据查询不可或缺的。由于这两个字段非常重要,我们可以将它们结合起来构建一个复合索引。
很多人认为只要在聚簇索引中加入任意一个字段,就可以提高查询速度。还有人不解:如果单独查询复合聚集索引字段,查询速度会不会变慢?带着这个问题,我们来看看下面的查询速度(结果集都是25万条数据):(日期列fariqi排在复合聚集索引的最前面,用户名neibuyonghu排在后面):

(1) select GID,fariqi,neibu胡勇,title from tgongwen where fari qi > ' ' 2004-5-5 ' '
查询速度:2513毫秒。

(2)从《大公报》中选择gid、fariqi、neibuyonghu、title

其中,法里基>“2004年5月5日”和内布胡勇=“办公室”
查询速度:2516毫秒

(3) Select GID,Fariqi,Neibu胡勇,Title from TGongwen where Neibu胡勇='' Office''
查询速度:60280ms

从上面的实验可以看出,如果只使用聚集索引的起始列作为查询条件,复合聚集索引的所有列的查询速度几乎相同,甚至略快于复合索引的所有列(查询结果集个数相同时);但是,如果只将复合聚集索引的非起始列用作查询条件,则该索引将不起作用。当然,语句1和语句2的查询速度是一样的,因为查询的项数是一样的。如果复合索引的所有列都被使用,查询结果很少,那么就会形成“索引覆盖”,这样性能就可以达到。同时,记住:不管你是否经常使用聚集索引的其他列,前导列必须是使用最频繁的列。

四。使用其他书中没有的索引的经验总结

1.使用聚合索引比使用非聚合索引的主键更快
下面是语句示例: (提取了250,000条数据)

Select GID,fariqi,neibu胡勇,reader,title from tgong Wen where fari qi = ' ' September 16 of 2004 ' '
使用时间:3326毫秒

Select GID,fariqi,neibu胡勇,reader,title from tgongwen where GID ' ' 2004-1-1 ' '
时间:6343毫秒(提取100万条)

Select GID,fariqi,neibu胡勇,reader,title from tgongwen where fari qi >“2004年6月6日”
时间:3170毫秒(提取了500,000个片段)

Select GID,fariqi,neibu胡勇,reader,title from tgongwen where fari qi = ' ' 2004-9-16 ' '
时间:3326毫秒(与上一句的结果完全相同。如果收集的数量相同,则大于号和等号相同)

选择gid,fariqi,neibuyonghu,reader,title from Tgongwen

其中Fariqi >“2004年1月1日”和fari qi“2004年1月1日”按fari qi排序
时间:6390毫秒

选择gid,fariqi,neibuyonghu,reader,title from Tgongwen

其中fariqi需要:6453毫秒

动词 (verb的缩写)其他需要注意的事项

“水能载舟,亦能覆舟”,指数也是如此。索引可以提高检索性能,但是过多或不适当的索引也会导致系统效率低下。因为每次用户向表中添加索引时,数据库都要做更多的工作。过多的索引甚至可能导致索引碎片。
因此,我们应该建立一个“合适的”索引系统,尤其是对于聚集索引的创建,力求完美,这样你的数据库才能达到高性能。
当然,在实际操作中,作为一个专门的数据库管理员,你要测试更多的方案,才能发现哪种方案是最高效、最有效的。


位律师回复
DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
白度搜_经验知识百科全书 » SQLServer索引结构及其使用(一)

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情