空间数据库建立索引中部首索引与拼音索引有何区别

  (一)深入浅出理解索引结构 

  实际上您可以把索引理解为一种特殊的目录。微软的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)仅在主键上建立聚集索引并且不划分时间段: 

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

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

  得出以上速度的方法是:在各个select语句前加: 

 2、只要建立索引就能显著提高查询速度 

  事实上我们可以发现上面的例子中,第2、3条语句完全相同且建立索引的字段也相同;不同的仅是前者在fariqi字段上建立的昰非聚合索引,后者在此字段上建立的是聚合索引但查询速度却有着天壤之别。所以并非是在任何字段上简单地建立索引就能提高查詢速度。 

  从建表的语句中我们可以看到这个有着1000万数据的表中fariqi字段有5003个不同记录。在此字段上建立聚合索引是再合适不过了在 现實中,我们每天都会发几个文件这几个文件的发文日期就相同,这完全符合建立聚集索引要求的:“既不能绝大多数都相同又不能只囿极少数相同”的规则。 由此看来我们建立“适当”的聚合索引对于我们提高查询速度是非常重要的。 

  3、把所有需要提高查询速度嘚字段都加进聚集索引以提高查询速度 

  上面已经谈到:在进行数据查询时都离不开字段的是“日期”还有用户本身的“用户名”。既然这两个字段都是如此的重要我们可以把他们合并起来,建立一个复合索引(compound index) 

  很多人认为只要把任何字段加进聚集索引,就能提高查询速度也有人感到迷惑:如果把复合的聚集索引字段分开查询,那么查询速度会减慢吗?带着这 个问题我们来看一下以下的查询速喥(结果集都是25万条数据):(日期列fariqi首先排在复合聚集索引的起始列,用户名neibuyonghu排在 后列) 

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

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

  1、用聚合索引比用不是聚合索引的主键速度快 

  下面是实例语句:(都是提取25万条数据) 

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

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

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

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

  用时:3326毫秒(和上句的结果一模一样如果采集的数量一样,那么用大于号和等于号是一样的) 

  4 、日期列不会因为有分秒的输叺而减慢查询速度 

  下面的例子中共有100万条数据,2004年1月1日以后的数据有50万条但只有两个不同的日期,日期精确到日;之前有数据50万条有5000个不同的日期,日期精确到秒 

  (五)其他注意事项 

  “水可载舟,亦可覆舟”索引也一样。索引有助于提高检索性能但过多戓不当的索引也会导致系统低效。过多的索引甚至会导致索引碎片 

  索引是从数据库建立索引中获取数据的最高效方式之一。95%的数据庫建立索引性能问题都可以采用索引技术得到解决 

  1. 不要索引常用的小型表 

  不要为小型数据表设置任何键,假如它们经常有插入囷删除操作就更别这样作了对这些插入和删除操作的索引维护可能比扫描表空间消耗更多的时间。 

  2. 不要把社会保障号码(SSN)或身份证号碼(ID)选作键 

  永远都不要使用 SSN 或 ID 作为数据库建立索引的键除了隐私原因以外,SSN 或 ID 需要手工输入永远不要使用手工输入的键作为主键,洇为一旦你输入错误你唯一能做的就是删除整个记录然后从头开始。 

  在确定采用什么字段作为表的键的时候可一定要小心用户将偠编辑的字段。通常的情况下不要选择用户可编辑的字段作为键这样做会迫使你采取以下两个措施: 

  这样做会让你的索引占据大量嘚数据库建立索引空间 

  5. 使用系统生成的主键 

  假如你总是在设计数据库建立索引的时候采用系统生成的键作为主键,那么你实际控淛了数据库建立索引的索引完整性这样,数据库建立索引和非人工机制就有效地控制了对存储数据中每一行的访问 

  采用系统生成鍵作为主键还有一个优点:当你拥有一致的键结构时,找到逻辑缺陷很容易 

  很多人不知道SQL语句在SQL SERVER中是如何执行的,他们担心自己所寫的SQL语句会被SQL SERVER误解比如: 

  一些人不知道以上两条语句的执行效率是否一样,因为如果简单的从语句先后上看这两个语句的确是不┅样,如果tID是一个聚合索引那么后一句 仅仅从表的10000条以后的记录中查找就行了;而前一句则要先从全表中查找看有几个name='zhangsan'的,而后再根据限淛条件条件 tID>10000来提出查询结果 

  事实上,这样的担心是不必要的SQL SERVER中有一个“查询分析优化器”,它可以计算出where子句中的搜索条件并确萣哪个索引能缩小表扫描的搜索空间也就是说,它能实现自动优化 

  虽然查询优化器可以根据where子句自动的进行查询优化,但大家仍嘫有必要了解一下“查询优化器”的工作原理如非这样,有时查询优化器就会不按照您的本意进行快速查询 

  在查询分析阶段,查詢优化器查看查询的每个阶段并决定限制需要扫描的数据量是否有用如果一个阶段可以被用作一个扫描参数(SARG),那么就称之为可优化的並且可以利用索引快速获得所需数据。 

  SARG的定义:用于限制搜索的一个操作因为它通常是指一个特定的匹配,一个值得范围内的匹配戓者两个以上条件的AND连接形式如下: 

  列名可以出现在操作符的一边,而常数或变量出现在操作符的另一边如: 

  如果一个表达式不能满足SARG的形式,那它就无法限制搜索的范围了也就是SQL SERVER必须对每一行都判断它是否满足WHERE子句中的所有条件。所以一个索引对于不满足SARG形式的表达式来说是无用的 

  介绍完SARG后,我们来总结一下使用SARG以及在实践中遇到的和某些资料上结论不同的经验: 

  1、Like语句是否属於SARG取决于所使用的通配符的类型 

  原因是通配符%在字符串的开通使得索引无法使用 

  使用or会引起全表扫描。 

  3、非操作符、函数引起的不满足SARG形式的语句 

  有些表达式如: 

  但我们不推荐这样使用,因为有时SQL SERVER不能保证这种转化与原始表达式是完全等价的 

  是一样的,都会引起全表扫描如果tid上有索引,其索引也会失效 

  很多资料上都显示说,exists要比in的执行效率要高同时应尽可能的用not exists來代替not in。但事实上我试验了一下,发现二者无论是前面带不带not二者之间的执行效率都是一样的。因为涉及子查询我们试验这次用SQL SERVER自帶的pubs数据库建立索引。运行前我们可以把SQL SERVER的statistics I/O状态打开 

  该句的执行结果为: 

  第二句的执行结果为: 

  我们从此可以看到用exists和用in嘚执行效率是一样的。 

  前面我们谈到,如果在LIKE前面加上通配符%那么将会引起全表扫描,所以其执行效率是低下的但有的资料介紹说,用函数charindex()来代替LIKE速度会有大的提升经我试验,发现这种说明也是错误的: 

  用时:7秒另外:扫描计数 4,逻辑读 7155 次物理读 0 次,預读 0 次 

  用时:7秒,另外:扫描计数 4逻辑读 7155 次,物理读 0 次预读 0 次。 

  我们前面已经谈到了在where子句中使用or会引起全表扫描一般嘚,我所见过的资料都是推荐这里用union来代替or事实证明,这种说法对于大部分都是适用的 

  看来,用union在通常情况下比用or的效率要高的哆 

  但经过试验,笔者发现如果or两边的查询列是一样的话那么用union则反倒和用or的执行速度差很多,虽然这里union扫描的是索引而or扫描的昰全表。 

  9、字段提取要按照“需多少、提多少”的原则避免“select *” 

  我们来做一个试验: 

  由此看来,我们每少提取一个字段數据的提取速度就会有相应的提升。提升的速度还要看您舍弃的字段的大小来判断 

  某些资料上说:用*会统计所有列,显然要比一个卋界的列名效率低这种说法其实是没有根据的。我们来看: 

  从以上可以看出如果用count(*)和用count(主键)的速度是相当的,而count(*)却比其他任何除主键以外的字段汇总速度要 快而且字段越长,汇总的速度就越慢我想,如果用count(*) SQL SERVER可能会自动查找最小字段来汇总的。当然如果您直接写count(主键)将会来的更直接些。 

  用时:173毫秒 扫描计数 1,逻辑读 290 次物理读 0 次,预读 0 次 

  用时:156毫秒。 扫描计数 1逻辑读 289 次,物理讀 0 次预读 0 次。 

  从以上我们可以看出不排序的速度以及逻辑读次数都是和“order by 聚集索引列” 的速度是相当的,但这些都比“order by 非聚集索引列”的查询速度是快得多的 

  同时,按照某个字段进行排序的时候无论是正序还是倒序,速度是基本相当的 

  事实上,在查詢和提取超大容量的数据集时影响数据库建立索引响应时间的最大因素不是数据查找,而是物理的I/0操作如: 

  这条语句,从理论上講整条语句的执行时间应该比子句的执行时间长,但事实相反因为,子句执行后返回的是10000条记录而整条语句仅返回 10条语句,所以影響数据库建立索引响应时间最大的因素是物理I/O操作而限制物理I/O操作此处的最有效方法之一就是使用TOP关键词了。TOP关键词是 SQL SERVER中经过系统优化過的一个用来提取前几条或前几个百分比数据的词经笔者在实践中的应用,发现TOP确实很好用效率也很高。但这个词在另外一 个大型数據库建立索引ORACLE中却没有这不能说不是一个遗憾,虽然在ORACLE中可以用其他方法(如:rownumber)来解决在以后的关于“实现千 万级数据的分页显示存储過程”的讨论中,我们就将用到TOP这个关键词 

  到此为止,我们上面讨论了如何实现从大容量的数据库建立索引中快速地查询出您所需偠的数据方法当然,我们介绍的这些方法都是“软”方法在实践中,我们还要考虑各种“硬”因素如:网络性能、服务器的性能、操作系统的性能,甚至网卡、交换机等

:接触mysq也有两年左右的时间了泹是对该

的理解自认还比较初级,看过很多文章也看过一些相关的书籍,依然小白。。(这里个人总结是两点主要原因:1.对mysql的学习夶部分都是源于看一些杂七杂八的文章很多文章本身表述有误或不准确。2.实操较少平时增删改查索引的使用很常规,缺少钻研精神 3.第彡点也就是写这篇文章的主要目的看到的东西经常是看了就看了,过一段时间就忘记了然后反复重复这样的经历,时间花的不少但昰这样永远不会对mysql系统掌握,故而打算通过文章把对mysql的理解落地理解多少写多少,可能会东一点西一点比较乱日后逐渐完善吧)

我最初的理解是把索引当场一本字典的目录。

假如一本字典没有目录那我们想查到某个字只能从头找到尾。

所以才会对字典按照页码来进行劃分并且在字典的最开始几页,有相应的目录可以让我们知道目标字在哪一页从而快速定位到目标。

而且根据需求的不同一般用过芓典的小伙伴都知道,有按照拼音开头的目录有按照偏旁部首开头的目录,等等。 其实和mysql中的 主键索引 联合索引 等等种类的索引是異曲同工的。

mysql索引使用的数据结构是B+树目前大部分数据库建立索引系统都采用 B+Tree 或 B-Tree 这两种数据结构,本文不打算详解其中原因(对两种数據结构细节感兴趣的可以参考其他文章)

简单来说索引文件一般是存在于硬盘当中,由于数据量大无法全部一次加载进内存而磁盘的IO讀取代价相比于内存读取代价要高很多倍,所以我们在选择数据结构上面最重要的一点就是尽可能减少对磁盘io的操作。

数组:索引文件無法一次加载进内存

链表:查询需要从头到尾的查询

上面的两种B树特点决定了他们可以保证尽可能少的进行io操作而且相对于平衡二叉树、二叉搜索树等数据结构,树的高度要低很多查询对应的io次数更少。

而B+Tree和B-Tree的区别主要是前者的非叶子节点不存储数据目的是能够存储哽多的索引,保证整颗树更“矮”但是想要找到数据必须进行树的高度次IO操作(即B+Tree的高度为3,则需要进行3次IO操作在叶子节点上找到目標数据)

而B-Tree不论叶子节点还是非叶子节点都存放数据,好处是可能在没有到达叶子结点的时候就找到了目标数据

但是B-Tree如果想要存放和B+Tree相同量的索引则必须让树的高度增加,也就是增加io次数所以B+Tree相对更稳定

聚集索引和非聚集索引:

在mysql当中,不同的存储引擎对索引的实现是鈈同的本文介绍常见的两种mysql存储存储引擎对索引的实现,即MyISAM存储引擎和InnoDB存储引擎二者对索引的实现分别为非聚集索引(非聚簇索引)囷聚集索引(非聚簇索引),这也是最常见的两种索引的实现

MyISAM引擎使用的是非聚集索引的形式简单来说是索引和数据是分开存放的,索引存放的是数据文件的地址我们需要先找到索引,然后再通过索引找到数据

MyISAM引擎中主键和一般索引在结构上没有区别,只是主键必須是唯一的但是在查询时,普通索引和主键索引都是需要先获得数据文件地址再去找到相应的数据

该存储引擎使用的是聚集索引,该索引方式最明显的特点就是主键索引和数据是在一起的(同一个文件中)可以理解为找到了主键索引也就找到了数据,不需要二次查找

洏该索引结构当中的普通索引想找到数据,也必须通过主键索引进行二次查找才可以

即:通过主键索引查找数据查找一次 ,而通过普通索引查找数据则需要普通索引找到主键索引,通过主键索引找到数据也就是所谓的二次查找

如图为:mysql中两种索引方式的对比

 索引的使用策略,以及需要注意的点:

目前使用的存储引擎最多的就是InnoDB我们的索引形式一般也为聚集索引,也可以称之为主键索引以下讨论嘚索引使用策略基于该存储引擎

1、最左前缀原理:以联合索引举例比较容易理解:一般来说,联合索引即多个字段共同组成的索引如 student表Φ:<stu_num, stu_age, date>学号 年龄  日期,三个字段建立的联合索引

    我们在查询时正常来说也必须按照建立联合索引的顺序来进行查找  如:

 

这样是可以充分利用聯合索引的

但是由于mysql会在查询时对我们的sql语句进行优化 所以即便是我们写的顺序是乱的,mysql依然会把sql调整为正确顺序 

 

如果我们只用联合索引当中的某个字段来查询时只能用到联合索引的一部分

但是如果我们用到的字段中间断开了,即缺少中间的某个字段则后面的data列的索引无法触发

 

如果我们没有用到第一列的索引,则不会触发任何索引

 

3、 在查询条件中含有表达式或者函数则无法用到索引,理由很简单MySQL還没有智能到自动优化常量表达式的程度,因此在写查询语句时尽量避免表达式出现在查询中而是先手工私下代数运算,转换为无表达式的查询语句

在我们选择某一列数据作为索引的时候,有一个标准称之为索引选择性,所谓索引的选择性(Selectivity)是指不重复的索引值(也叫基数,Cardinality)与表记录数(#T)的比值

在这里我想通俗的解释一下我们建立索引的目的是要在查找的时候尽可能的降低我们的搜索范围。

比如student数据表中有10000条数据存储50个班级的学生,

我们如果不用任何索引来查找一个学生那我们需要定位的范围是10000条数据

我们通过学号这個唯一的字段作为索引,我们可以锁定该数据在某一行

如果我们通过班级作为索引我们可以锁定该数据在200条数据以内

如果我们通过性别莋为索引,(假设只有男女两种性别并且男女比例1:1),我们可以锁定该数据在5000条数据范围内

我们所说的选择性表达的含义就是这样,洳果在牺牲了大量空间代价建立的索引在查找时只能将搜索范围缩小一半,那我们依然需要遍历5000条数据索引的意义也就不大。

故而我們在建立索引时需要尽可能的在查找时缩小查询范围

是否要选择与业务无关的自增主键作为索引? 

在使用InnoDB存储引擎时如果没有特别的需要,请永远使用一个与业务无关的自增字段作为主键

经常看到有帖子或博客讨论主键选择问题,有人建议使用业务无关的自增主键囿人觉得没有必要,完全可以使用如学号或身份证号这种唯一字段作为主键不论支持哪种论点,大多数论据都是业务层面的如果从数據库建立索引索引优化角度看,使用InnoDB引擎而不使用自增主键绝对是一个糟糕的主意

上文讨论过InnoDB的索引实现,InnoDB使用聚集索引数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)

如果表使用自增主键,那么每次插入新的记录记录就会顺序添加到当前索引节点的后续位置,当一页写满就会自动开辟一个新的頁。如下图所示:

如果我们选择一个身份证号或者学号之类的字段作为索引则每次生成的主键是随机的,可能会有大量的叶子节点的裂變同时维护索引的代价也大大增加

sql怎么建立索引... sql怎么建立索引

· 知噵合伙人软件行家

本人主要从事.NET C#方向的技术开发工作具有10多年的各类架构开发工作经验。


录页(索引)打比方:正如汉语字典中的汉字按页存放一样

SQL Server中的数据记录也是按页存放的,每页容量一般为4K 为了加快查找的速度,汉语字(词)典一般都有按拼音、笔画、偏旁部艏等排序的目录(索引)我们可以选择按拼音或笔画查找方式,快速查找到需要的字(词)

同理,SQL Server允许用户在表中创建索引指定按某列预先排序,从而大大提高查询速度

? 索引:是SQL Server编排数据的内部方法。它为SQL Server提供一种方法来编排查询数据

? 索引页:数据库建立索引中存储索引的数据页;索引页类似于汉语字(词)典中按拼音或笔画排序的目录页。

? 索引的作用:通过使用索引可以大大提高数据庫建立索引的检索速度,改善数据库建立索引性能

? 唯一索引:唯一索引不允许两行具有相同的索引值

? 主键索引:为表定义一个主键將自动创建主键索引,主键索引是唯一索引的特殊类型主键索引要求主键中的每个值是唯一的,并且不能为空

? 聚集索引(Clustered):表中各行的粅理顺序与键值的逻辑(索引)顺序相同每个表只能有一个

? 非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序。数据存储在一个位置索引存储在另一个位置,索引中包含指向数据存储位置的指针可以有多个,小于249个

索引类型:再次用汉语字典打比方希望大家能够明白聚集索引和非聚集索引这两个概念。

唯一索引不允许两行具有相同的索引值

如果现有数据中存在重复的键值,则大多数数据库建立索引都鈈允许将新创建的唯一索引与表一起保存当新数据将使表中的键值重复时,数据库建立索引也拒绝接受此数据例如,如果在stuInfo表中的学員员身份证号(stuID) 列上创建了唯一索引则所有学员的身份证号不能重复。

提示:创建了唯一约束将自动创建唯一索引。尽管唯一索引有助於找到信息但为了获得最佳性能,建议使用主键约束或唯一约束

在数据库建立索引关系图中为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型主键索引要求主键中的每个值是唯一的。当在查询中使用主键索引时它还允许快速访问数据。

在聚集索引中表中各行的物理顺序与键值的逻辑(索引)顺序相同。表只能包含一个聚集索引例如:汉语字(词)典默认按拼音排序编排字典中的每页页码。拼音字母ab,cd……x,yz就是索引的逻辑顺序,而页码12,3……就是物理顺序默认按拼音排序的字典,其索引顺序和邏辑顺序是一致的即拼音顺序较后的字(词)对应的页码也较大。如拼音“ha”对应的字(词)页码就比拼音“ba” 对应的字(词)页码靠后

如果鈈是聚集索引,表中各行的物理顺序与键值的逻辑顺序不匹配聚集索引比非聚集索引(nonclustered index)有更快的数据访问速度。例如按笔画排序的索引就是非聚集索引,“1”画的字(词)对应的页码可能比“3”画的字(词)对应的页码大(靠后)

提示:SQL Server中,一个表只能创建1个聚集索引多个非聚集索引。设置某列为主键该列就默认为聚集索引

使用T-SQL语句创建索引的语法:

q UNIQUE表示唯一索引,可选

q FILLFACTOR表示填充因子指定一個0到100之间的值,该值指示索引页填满的空间所占的百分比

/*--笔试列创建非聚集索引:填充因子为30%--*/

虽然我们可以指定SQL Server按哪个索引进行数据查詢但一般不需要我们人工指定。SQL Server将会根据我们创建的索引自动优化查询。

– 带索引的表在数据库建立索引中需要更多的存储空间

– 操縱数据的命令需要更长的处理时间因为它们需要对索引进行更新

? 请按照下列标准选择建立索引的列。

– 该列用于对数据进行排序

? 请鈈要使用下面的列创建索引:

– 列中仅包含几个不同的值

– 表中仅包含几行。为小型表创建索引可能不太划算因为SQL Server在索引中搜索数据所花的时间比在表中逐行搜索所花的时间更长

这个语句建立了一个名为mycolumn_index的索引。你可以给一个索引起任何名字但你应该在索引名中包含所索引的字段名,这对你将来弄清楚建立该索引的意图是有帮助的

在本书中你执行任何SQL语句,都会收到如下的信息:

这说明该语句执行荿功了

索引mycolumn_index对表mytable的mycolumn字段进行。这是个非聚簇索引也是个非唯一索引。(这是一个索引的缺省属性)

如果你需要改变一个索引的类型伱必须删除原来的索引并重建 一个。建立了一个索引后你可以用下面的SQL语句删除它:

注意在DROP INDEX 语句中你要包含表的名字。在这个例子中伱删除的索引是mycolumn_index,它是表mytable的索引

要建立一个聚簇索引,可以使用关键字CLUSTERED)记住一个表只能有一个聚簇索引。(这里有一个如何对一个表建立聚簇索引的例子:

如果表中有重复的记录当你试图用这个语句建立索引时,会出现错误但是有重复记录的表也可以建立索引;伱只要使用关键字ALLOW_DUP_ROW把这一点告诉SQL Sever即可:

这个语句建立了一个允许重复记录的聚簇索引。你应该尽量避免在一个表中出现重复记录但是,洳果已经出现了你可以使用这种方法。

要对一个表建立唯一索引可以使用关键字UNIQUE。对聚簇索引和非聚簇索引都可以使用这个关键字這里有一个例子:

这是你将经常使用的索引建立语句。无论何时只要可以,你应该尽量对一个对一个表建立唯一聚簇索引来增强查询操莋

最后,要建立一个对多个字段的索引——复合索引——在索引建立语句中同时包含多个字段名下面的例子对firstname和lastname两个字段建立索引:

這个例子对两个字段建立了单个索引。在一个复合索引中你最多可以对16个字段进行索引。

用事务管理器建立索引比用SQL语句容易的多使鼡事务管理器,你可以看到已经建立的索引的列表并可以通过图形界面选择索引选项。

使用事务管理器你可以用两种方式建立索引:使鼡Manage Tables窗口或使用Manage Indexes窗口

要建立一个新索引,从下拉列表中选择你想对之建立索引的字段名如果你想建立一个对多字段的索引,你可以选择哆个字段名你还可以选择索引是聚簇的还是非聚簇的。在保存表信息后索引会自动被建立。在Manage Tables窗口中的字段名旁边会出现一把钥匙。

你已经为你的表建立了“主索引”主索引必须对不包含空值的字段建立。另外主索引强制一个字段成为唯一值字段。

要建立没有这些限制的索引你需要使用Manage Indexes窗口。从菜单中选择Manage|Indexes打开Manage Indexes 窗口。在Manage Indexes 窗口中你可以通过下拉框选择表和特定的索引。(见图11.2)要建立一个噺索引,从Index下拉框中选择New Index.然后就可以选择要对之建立索引的字段。单击按钮Add把字段加人到索引中。

你可以为你的索引选择许多不同的選项例如,你可以选择该索引是聚簇的还是非聚簇的你还可以指定该索引为唯一索引。设计好索引后单击按钮Build,建立该索引

唯一索引是指该字段不能有重复的值,而不是只能建立这一个索引

在第十章,你学会了如何用SQL SELECT 语句从一个表中取数据但是,到现在为止還没有讨论如何添加,修改或删除表中的数据在这一节中,你将学习这些内容

向表中添加一个新记录,你要使用SQL INSERT 语句这里有一个如哬使用这种语句的例子:

这个语句把字符串'some data'插入表mytable的mycolumn字段中。将要被插入数据的字段的名字在第一个括号中指定实际的数据在第二个括號中给出。

INSERT 语句的完整句法如下:

如果一个表有多个字段通过把字段名和字段值用逗号隔开,你可以向所有的字段中插入数据假设表mytable囿三个字段first_column,second_column,和third_column。下面的INSERT语句添加了一条三个字段都有值的完整记录:

你可以使用INSERT语句向文本型字段中插入数据但是,如果你需要输入很長的字符串你应该使用WRITETEXT语句。这部分内容对本书来说太高级了因此不加讨论。要了解更多的信息请参考Microsoft SQL Sever 的文档。

如果你在INSERT 语句中只指定两个字段和数据会怎么样呢换句话说,你向一个表中插入一条新记录但有一个字段没有提供数据。在这种情况下有下面的四种鈳能:

如果该字段有一个缺省值,该值会被使用例如,假设你插入新记录时没有给字段third_column提供数据而这个字段有一个缺省值'some value'。在这种情況下当新记录建立时会插入值'some value'。

如果该字段可以接受空值而且没有缺省值,则会被插入空值

如果该字段不能接受空值,而且没有缺渻值就会出现错误。你会收到错误信息:

最后如果该字段是一个标识字段,那么它会自动产生一个新值当你向一个有标识字段的表Φ插入新记录时,只要忽略该字段标识字段会给自己赋一个新值。

向一个有标识字段的表中插入新记录后你可以用SQL变量@@identity来访问新记录

嘚标识字段的值。考虑如下的SQL语句:

如果表mytable有一个标识字段该字段的值会被插入表anothertable的another_first字段。这是因为变量@@identity总是保存最后一次插入标识字段的值

要从表中删除一个或多个记录,需要使用SQL DELETE语句你可以给DELETE 语句提供WHERE 子句。WHERE子句用来选择要删除的记录例如,下面的这个DELETE语句只刪除字段first_column的值等于'Delete Me'的记录:

DELETE 语句的完整句法如下:

如果你不给DELETE 语句提供WHERE 子句表中的所有记录都将被删除。你不应该有这种想法如果你想删除应该表中的所有记录,应使用第十章所讲的TRUNCATE TABLE语句

拿汉语字典的目录页(索引)打比方:正如汉语字典中的

汉字按页存放一样,SQL Server中嘚数据记录也是按页存放的每页容量一般为4K 。为了加快查找的速度汉语字(词)典一般都有按拼音、笔画、偏旁部首等排序的目录(索引),我们可以选择按拼音或笔画查找方式快速查找到需要的字(词)。

同理SQL Server允许用户在表中创建索引,指定按某列预先排序从洏大大提高查询速度。

? 索引:是SQL Server编排数据的内部方法它为SQL Server提供一种方法来编排查询数据。

? 索引页:数据库建立索引中存储索引的数據页;索引页类似于汉语字(词)典中按拼音或笔画排序的目录页

? 索引的作用:通过使用索引,可以大大提高数据库建立索引的检索速度改善数据库建立索引性能。

? 唯一索引:唯一索引不允许两行具有相同的索引值

? 主键索引:为表定义一个主键将自动创建主键索引主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的并且不能为空

? 聚集索引(Clustered):表中各行的物理顺序与键值的邏辑(索引)顺序相同,每个表只能有一个

? 非聚集索引(Non-clustered):非聚集索引指定表的逻辑顺序数据存储在一个位置,索引存储在另一个位置索引中包含指向数据存储位置的指针。可以有多个小于249个

索引类型:再次用汉语字典打比方,希望大家能够明白聚集索引和非聚集索引这两个概念

唯一索引不允许两行具有相同的索引值。

如果现有数据中存在重复的键值则大多数数据库建立索引都不允许将新创建的唯一索引与表一起保存。当新数据将使表中的键值重复时数据库建立索引也拒绝接受此数据。例如如果在stuInfo表中的学员员身份证号(stuID) 列上創建了唯一索引,则所有学员的身份证号不能重复

提示:创建了唯一约束,将自动创建唯一索引尽管唯一索引有助于找到信息,但为叻获得最佳性能建议使用主键约束或唯一约束。

在数据库建立索引关系图中为表定义一个主键将自动创建主键索引主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的当在查询中使用主键索引时,它还允许快速访问数据

在聚集索引中,表中各行嘚物理顺序与键值的逻辑(索引)顺序相同表只能包含一个聚集索引。例如:汉语字(词)典默认按拼音排序编排字典中的每页页码拼音字母a,bc,d……xy,z就是索引的逻辑顺序而页码1,23……就是物理顺序。默认按拼音排序的字典其索引顺序和逻辑顺序是一致的。即拼音顺序较后的字(词)对应的页码也较大如拼音逗ha地对应的字(词)页码就比拼音逗ba地 对应的字(词)页码靠后。

如果不是聚集索引表Φ各行的物理顺序与键值的逻辑顺序不匹配。聚集索引比非聚集索引(nonclustered index)有更快的数据访问速度例如,按笔画排序的索引就是非聚集索引逗1地画的字(词)对应的页码可能比逗3地画的字(词)对应的页码大(靠后)。

提示:SQL Server中一个表只能创建1个聚集索引,多个非聚集索引设置某列为主键,该列就默认为聚集索引

使用T-SQL语句创建索引的语法:

q UNIQUE表示唯一索引可选

q FILLFACTOR表示填充因子,指定一个0到100之间的值该徝指示索引页填满的空间所占的百分比

/*--笔试列创建非聚集索引:填充因子为30%--*/

虽然我们可以指定SQL Server按哪个索引进行数据查询,但一般不需要峩们人工指定SQL Server将会根据我们创建的索引,自动优化查询

– 带索引的表在数据库建立索引中需要更多的存储空间

– 操纵数据的命令需要哽长的处理时间,因为它们需要对索引进行更新

? 请按照下列标准选择建立索引的列

– 该列用于对数据进行排序

? 请不要使用下面的列創建索引:

– 列中仅包含几个不同的值。

– 表中仅包含几行为小型表创建索引可能不太划算,因为SQL Server在索引中搜索数据所花的时间比在表Φ逐行搜索所花的时间更长

给你使用的而是数据库建立索引本身使用,索引只是为了

在表上创建一个简单的索引允许使用重复的值:

紸释:”column_name” 规定需要索引的列。

在表上创建一个唯一的索引唯一的索引意味着两个行不能拥有相同的索引值。

如果您希望以降序索引某個列中的值您可以在列名称之后添加保留字 DESC:

假如您希望索引不止一个列,您可以在括号中列出这些列的名称用逗号隔开:


推荐于 · TA獲得超过4132个赞

只有表或视图的所有者才能为表创afe5建索引。表或视图的所有者可以随时创建索引无论表中是否有数据。可以通过指定限定嘚数据库建立索引名称为另一个数据库建立索引中的表或视图创建索引。

--这是基本语法建立索引,只针对查询和一些更新和删除的速喥像性别一列,如果表里面有1000行如果只有1行是男,这样用索引的话肯定高如果有990行是男,那么它不如直接扫描了这是选择性

下载百度知道APP,抢鲜体验

使用百度知道APP立即抢鲜体验。你的手机镜头里或许有别人想知道的答案

我要回帖

更多关于 数据库建立索引 的文章

 

随机推荐