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

作者&投稿:莱怀 (若有异议请与网页底部的电邮联系)
~ 一、深入浅出理解索引结构

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

二、何时使用聚集索引或非聚集索引

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

动作描述 使用聚集索引 使用非聚集索引 列经常被分组排序 应 应 返回某范围内的数据 应 不应 一个或极少不同值 不应 不应 小数目的不同值 应 不应 大数目的不同值 不应 应 频繁更新的列 不应 应 外键列 应 应 主键列 应 应 频繁修改索引列 不应 应
  事实上,我们可以通过前面聚集索引和非聚集索引的定义的例子来理解上表。如:返回某范围内的数据一项。比如您的某个表有一个时间列,恰好您把聚合索引建立在了该列,这时您查询2004年1月1日至2004年10月1日之间的全部数据时,这个速度就将是很快的,因为您的这本字典正文是按日期进行排序的,聚类索引只需要找到要检索的所有数据中的开头和结尾数据即可;而不像非聚集索引,必须先查到目录中查到每一项数据对应的页码,然后再根据页码查到具体内容。

三、结合实际,谈索引使用的误区

  理论的目的是应用。虽然我们刚才列出了何时应使用聚集索引或非聚集索引,但在实践中以上规则却很容易被忽视或不能根据实际情况进行综合分析。下面我们将根据在实践中遇到的实际问题来谈一下索引使用的误区,以便于大家掌握索引建立的方法。

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

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

Select gid,fariqi,neibuyonghu,title from tgongwen
用时:128470毫秒(即:128秒)

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

select gid,fariqi,neibuyonghu,title from Tgongwen

where fariqi> dateadd(day,-90,getdate())
用时:53763毫秒(54秒)

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

select gid,fariqi,neibuyonghu,title from Tgongwen

where fariqi> dateadd(day,-90,getdate())
用时:2423毫秒(2秒)

  虽然每条语句提取出来的都是25万条数据,各种情况的差异却是巨大的,特别是将聚集索引建立在日期列时的差异。事实上,如果您的数据库真的有1000万容量的话,把主键建立在ID列上,就像以上的第1、2种情况,在网页上的表现就是超时,根本就无法显示。这也是我摒弃ID列作为聚集索引的一个最重要的因素。得出以上速度的方法是:在各个select语句前加:

declare @d datetime

set @d=getdate()
并在select语句后加:

select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())
2、只要建立索引就能显著提高查询速度
  事实上,我们可以发现上面的例子中,第2、3条语句完全相同,且建立索引的字段也相同;不同的仅是前者在fariqi字段上建立的是非聚合索引,后者在此字段上建立的是聚合索引,但查询速度却有着天壤之别。所以,并非是在任何字段上简单地建立索引就能提高查询速度。
  从建表的语句中,我们可以看到这个有着1000万数据的表中fariqi字段有5003个不同记录。在此字段上建立聚合索引是再合适不过了。在现实中,我们每天都会发几个文件,这几个文件的发文日期就相同,这完全符合建立聚集索引要求的:“既不能绝大多数都相同,又不能只有极少数相同”的规则。由此看来,我们建立“适当”的聚合索引对于我们提高查询速度是非常重要的。

3、把所有需要提高查询速度的字段都加进聚集索引,以提高查询速度
  上面已经谈到:在进行数据查询时都离不开字段的是“日期”还有用户本身的“用户名”。既然这两个字段都是如此的重要,我们可以把他们合并起来,建立一个复合索引(compound index)。
  很多人认为只要把任何字段加进聚集索引,就能提高查询速度,也有人感到迷惑:如果把复合的聚集索引字段分开查询,那么查询速度会减慢吗?带着这个问题,我们来看一下以下的查询速度(结果集都是25万条数据):(日期列fariqi首先排在复合聚集索引的起始列,用户名neibuyonghu排在后列):

(1)select gid,fariqi,neibuyonghu,title from Tgongwen where fariqi>''2004-5-5''
查询速度:2513毫秒

(2)select gid,fariqi,neibuyonghu,title from Tgongwen

            where fariqi>''2004-5-5'' and neibuyonghu=''办公室''
查询速度:2516毫秒

(3)select gid,fariqi,neibuyonghu,title from Tgongwen where neibuyonghu=''办公室''
查询速度:60280毫秒

  从以上试验中,我们可以看到如果仅用聚集索引的起始列作为查询条件和同时用到复合聚集索引的全部列的查询速度是几乎一样的,甚至比用上全部的复合索引列还要略快(在查询结果集数目一样的情况下);而如果仅用复合聚集索引的非起始列作为查询条件的话,这个索引是不起任何作用的。当然,语句1、2的查询速度一样是因为查询的条目数一样,如果复合索引的所有列都用上,而且查询结果少的话,这样就会形成“索引覆盖”,因而性能可以达到。同时,请记住:无论您是否经常使用聚合索引的其他列,但其前导列一定要是使用最频繁的列。

四、其他书上没有的索引使用经验总结

1、用聚合索引比用不是聚合索引的主键速度快
  下面是实例语句:(都是提取25万条数据)

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=''2004-9-16''
使用时间:3326毫秒

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where gid<=250000
使用时间:4470毫秒

这里,用聚合索引比用不是聚合索引的主键速度快了近1/4。

2、用聚合索引比用一般的主键作order by时速度快,特别是在小数据量情况下

select gid,fariqi,neibuyonghu,reader,title from Tgongwen order by fariqi
用时:12936

select gid,fariqi,neibuyonghu,reader,title from Tgongwen order by gid
用时:18843

  这里,用聚合索引比用一般的主键作order by时,速度快了3/10。事实上,如果数据量很小的话,用聚集索引作为排序列要比使用非聚集索引速度快得明显的多;而数据量如果很大的话,如10万以上,则二者的速度差别不明显。

3、使用聚合索引内的时间段,搜索时间会按数据占整个数据表的百分比成比例减少,而无论聚合索引使用了多少个:

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>''2004-1-1''
用时:6343毫秒(提取100万条)

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi>''2004-6-6''
用时:3170毫秒(提取50万条)

select gid,fariqi,neibuyonghu,reader,title from Tgongwen where fariqi=''2004-9-16''
用时:3326毫秒(和上句的结果一模一样。如果采集的数量一样,那么用大于号和等于号是一样的)

select gid,fariqi,neibuyonghu,reader,title from Tgongwen

            where fariqi>''2004-1-1'' and fariqi<''2004-6-6''
用时:3280毫秒

4、日期列不会因为有分秒的输入而减慢查询速度
  下面的例子中,共有100万条数据,2004年1月1日以后的数据有50万条,但只有两个不同的日期,日期精确到日;之前有数据50万条,有5000个不同的日期,日期精确到秒。

select gid,fariqi,neibuyonghu,reader,title from Tgongwen

          where fariqi>''2004-1-1'' order by fariqi
用时:6390毫秒

select gid,fariqi,neibuyonghu,reader,title from Tgongwen

            where fariqi<''2004-1-1'' order by fariqi
用时:6453毫秒

五、其他注意事项

  “水可载舟,亦可覆舟”,索引也一样。索引有助于提高检索性能,但过多或不当的索引也会导致系统低效。因为用户在表中每加进一个索引,数据库就要做更多的工作。过多的索引甚至会导致索引碎片。
  所以说,我们要建立一个“适当”的索引体系,特别是对聚合索引的创建,更应精益求精,以使您的数据库能得到高性能的发挥。
  当然,在实践中,作为一个尽职的数据库管理员,您还要多测试一些方案,找出哪种方案效率、最为有效。


SQL SERVER 2008 R2 是干什么用的 具体怎么用 看到网站主机上有这样一...
QL ServerSQL Server 是一个关系数据库管理系统。它最初是由Microsoft、Sybase 和Ashton-Tate三家公司共同开发的,于1988 年推出了第一个OS\/2 版本。在Windows NT 推出后,Microsoft与Sybase 在SQL Server 的开发上就分道扬镳了,Microsoft 将SQL Server 移植到Windows NT系统上,专注于开发推广SQL Ser...

qls server(sqlexpress启动不了) 求解啊
在配置管理器的网络协议中启用tcp\/ip协议

怎样鎠ql server profiler的跟踪结果
1. 拥有 ALTERTRACE 权限的用户 A 开始重播跟踪。2. 在重播的跟踪中遇到用户 B 的登录事件。3. SQL Server Profiler 使用 EXECUTE AS命令模拟用户 2。4. SQL Server 尝试验证用户 B的身份,根据结果的不同会出现下列情况之一:如果用户 B 无法通过身份验证,SQLServer Profiler 将返回一个错误,并...

sol server profiler登录密码
QL Server默认用户名是sa,密码是安装的时候设置的密码,连接服务器的时候选择SQL Server身份验证,输入用户名和密码就完成了如果忘记了安装设置的默认密码,选择Windows身份验证,然后进去修改默认用户的密码就可以了;进去之后,点击安全性,登录名,sa鼠标右键sa用户,选择属性,进去之后,输入要设置的密码...

sqlserver 怎么查询iops高的原因
QL Server数据库查询速度慢的原因有很多,常见的有以下几种:1、没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷)2、I\/O吞吐量小,形成了瓶颈效应。3、没有创建计算列导致查询不优化。SQL Server查询速度慢原因4、内存不足 5、网络速度慢 6、查询出的数据量过大(可以采用多次...

SQL Server 2016怎么用
1 QL Server 2016怎么下载,我们可以在网上搜索一下就会有大把的地址,我们依据网上所指的官方下载地址进入。2 进入下载地址页面后,我们这里要记得自己在微软注册的帐户,如果没有请重新注册一个。3 登陆后在下载页面下方,我们找到自己要下载的SQL Server 2016格式版本,选择好版本后,我们再点击下面的...

sql2008安装,求大神帮忙
QL Server 2008(sql2008)由微软公司推出的大型的关系型数据库系统软件,专门用于大批量的数据存储和管理,适合服务器数据管理。其中SQL Server 2008是一个重大更新的产品版本,增加许多新的特性和关键的改进,使得它成为至今为止的最强大和最全面的SQL Server版本。请点击这里查看原因 ...

如何配置SQL Server 2008管理器
QL Server 配置附案例七可以通过开始菜单栏中的【SQL Server 2配置管理器】打开,或者通过在命令提示下输入sqlservermanager.msc命令来打开。2 首先打开SQL Server 配置管理器,查看列出的与SQL Server 2008相关的服务,选择服务名并右键单击弹出的快捷菜单中选择【属性】命令进行配置。在右键单击SQL Ser...

局域网内连接SQL SERVER访问被拒绝
QL Server 不存在或拒绝访问在网上找到的相关的解决方法:(A)1:你如果是独立上网的请把21端口打开.局域网把1433端口打开就可以了.2;关闭防火墙!(B)把数据库连接的 SqlLocalName="(local)" 的(local) 改成 IP试试。可以把(local) 该成127.0.0.1,或者改成外网IP (C)打开服务,暂停全文...

用VS2008连接sql server数据库的时候出现了这个错误框,怎么破?_百度...
QL Server 2008基于SQL Server 2005,并提供了更可靠的加强了数据库镜像的平台。解决方案一,下载SQL Server 2008 R2 并安装,然后你就可以正常使用了 ,解决方案二:首先, 找一台装有SQL Server 2008的电脑(或者更高版本,sql2012 等等), 将你的数据库文件附加到这台电脑里.附加成功后, 在SSMS...

屏南县15380955596: SQLServer索引结构是什么如何使用?
申炒幼泻: 聚集索引的重要性和如何选择聚集索引 在上一节的标题中,笔者写的是:实现小数据量和海量数据的通用分页显示存储过程.这是因为在将本存储过程应用于“办公自动化...

屏南县15380955596: SQLServer索引结构如何使用?
申炒幼泻: 改善SQL语句 很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所写的SQL语句会被SQL SERVER误解.比如: select * from table1 where name='...

屏南县15380955596: SQLServer索引结构及其使用情况如何呢?
申炒幼泻: 建立一个 Web 应用,分页浏览功能必不可少.这个问题是数据库处理中十分常见的... 但很明显,在SQL SERVER中,用临时表是没有用表变量快的.所以笔者刚开始使用...

屏南县15380955596: 如何使用sql server数据库索引??
申炒幼泻: create clustered index My_index(索引名) on StuInfo(StuID) (表的字段名) --创建聚集索引goselect * from StuInfo(表名) With (index=My_index) --查询索引哈哈 ,芋头现在在哪里干嘛呢....

屏南县15380955596: sql server索引怎么用 -
申炒幼泻: 1、打开 SQL Server Management Studio并连接到数据库引擎数据库.2、在“对象资源管理器”窗格中展开“数据库”节点.再打开“数据库”节点下的“表”节点,再展开dbo.格式的表.3、右击“索引”选项,在弹出的快捷菜单中选择“新建索引”命令.4、在打开的“新建索引”对话框中,设置索引的名称,索引类型为“聚集”, 然后单击“添加”按钮.5、在打开的 “从dbo.表 中选择列” 对话框中选择要添加到索引键的表列. 然后点击“确定”按钮.6、选择索引键后的“新建索引”对话框中,设置索引列的排序为“升序/降序”,设置完成后,单击“新建索引”对话框的“确定”按钮,这样就为表创建了索引.

屏南县15380955596: 数据库索引是什么,有什么用,怎么用 -
申炒幼泻: 索引是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度.索引包含由表或视图中的一列或多列生成的键.这些键存储在一个结构(B 树)中,使 SQL Server 可以快速有效地查找与键值关联的行.索引其实关键目的是为了加快检索速度而建立的,所以,怎么用索引是数据库系统本身的事情,作为数据库设计或使用者,设计并创建好索引然后体验加上索引后的查询变快的感觉就行了.所以,索引怎么用就变为了“怎么创建合适的索引”

屏南县15380955596: 在SQL SERVER中索引是什么 -
申炒幼泻: 一般格式为: CREATE [UNIQUE] [CLUSTER] INDEX ON ( [] [,[]]…); 索引的有关说明 可以动态地定义索引,即可以随时建立和删除索引 不允许用户在数据操作中引用索引.索引如何使用完全由系统决定,这支持了数据的物理独立性 应该在使用频率高的、经常用于连接的列上建索引 一个表上可建多个索引.索引可以提高查询效率,但索引过多耗费空间,且降低了插入、删除、更新的效率

屏南县15380955596: sql server2005数据库中的索引怎么使用
申炒幼泻: 举个例子.我有一个数据库tableA,中有100w条记录.在查询select * from tableA where columnA = 'A'的时候非常慢,这里就要进行优化... 第一个办法就是将columnA建立索引,加快查询速度. 缺点就是,查询操作的速度提高了,但是insert,update,delete操作所需要的时间就长了,因为每一次操作之后会更新索引.不过也不用太担心,数据库可以处理这些事情,对于用户体验上不会损失太少.

屏南县15380955596: SQLServer全文索引的正确使用流是怎样的?
申炒幼泻: 1).安装full text search全文索引服务; 2).为数据表建立full text catalog全文索引目录; 3).进行full text catalog的population操作(使全文索引与数据表内容同步); 4)....

屏南县15380955596: sql2005数据库如何使用索引? -
申炒幼泻: 创建索引可以直接在对象资源管理器中选择表---->关系---->自己创建索引,也可以通过语句创建,方法: --创建聚集索引,可以提供查询速度 create clustered index 索引名 on 表名(列名) with fillfactor = 50 --这是指填充因子 go 创建索引后查询方法如下: select 列名 from 表名(index=你创建的索引名)+条件

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网