First we try, then we trust

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  183 随笔 :: 111 文章 :: 2981 评论 :: 339 引用

在《数据库原理》里面,对聚簇索引的解释是:聚簇索引的顺序就是数据的物理存储顺序,而对非聚簇索引的解释是:索引顺序与数据物理排列顺序无关。正式因为如此,所以一个表最多只能有一个聚簇索引。

不过这个定义太抽象了。在SQL Server中,索引是通过二叉树的数据结构来描述的,我们可以这么理解聚簇索引:索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块。如下图:


非聚簇索引

 


聚簇索引


聚簇索引与非聚簇索引的本质区别到底是什么?什么时候用聚簇索引,什么时候用非聚簇索引?

这是一个很复杂的问题,很难用三言两语说清楚。我在这里从SQL Server索引优化查询的角度简单谈谈(如果对这方面感兴趣的话,可以读一读微软出版的《Microsoft SQL Server 2000数据库编程》第3单元的数据结构引论以及第6、13、14单元)。


一、索引块与数据块的区别

大家都知道,索引可以提高检索效率,因为它的二叉树结构以及占用空间小,所以访问速度块。让我们来算一道数学题:如果表中的一条记录在磁盘上占用1000字节的话,我们对其中10字节的一个字段建立索引,那么该记录对应的索引块的大小只有10字节。我们知道,SQL Server的最小空间分配单元是“页(Page)”,一个页在磁盘上占用8K空间,那么这一个页可以存储上述记录8条,但可以存储索引800条。现在我们要从一个有8000条记录的表中检索符合某个条件的记录,如果没有索引的话,我们可能需要遍历8000条×1000字节/8K字节=1000个页面才能够找到结果。如果在检索字段上有上述索引的话,那么我们可以在8000条×10字节/8K字节=10个页面中就检索到满足条件的索引块,然后根据索引块上的指针逐一找到结果数据块,这样IO访问量要少的多。


二、索引优化技术

是不是有索引就一定检索的快呢?答案是否。有些时候用索引还不如不用索引快。比如说我们要检索上述表中的所有记录,如果不用索引,需要访问8000条×1000字节/8K字节=1000个页面,如果使用索引的话,首先检索索引,访问8000条×10字节/8K字节=10个页面得到索引检索结果,再根据索引检索结果去对应数据页面,由于是检索所有数据,所以需要再访问8000条×1000字节/8K字节=1000个页面将全部数据读取出来,一共访问了1010个页面,这显然不如不用索引快。

SQL Server内部有一套完整的数据检索优化技术,在上述情况下,SQL Server的查询计划(Search Plan)会自动使用表扫描的方式检索数据而不会使用任何索引。那么SQL Server是怎么知道什么时候用索引,什么时候不用索引的呢?SQL Server除了日常维护数据信息外,还维护着数据统计信息,下图是数据库属性页面的一个截图:

从图中我们可以看到,SQL Server自动维护统计信息,这些统计信息包括数据密度信息以及数据分布信息,这些信息帮助SQL Server决定如何制定查询计划以及查询是是否使用索引以及使用什么样的索引(这里就不再解释它们到底如何帮助SQL Server建立查询计划的了)。我们还是来做个实验。建立一张表:tabTest(ID, unqValue,intValue),其中ID是整形自动编号主索引,unqValue是uniqueidentifier类型,在上面建立普通索引,intValue 是整形,不建立索引。之所以挂上一个没有索引的intValue字段,就是防止SQL Server使用索引覆盖查询优化技术,这样实验就起不到作用了。向表中录入10000条随机记录,代码如下:

CREATE TABLE [dbo].[tabTest] (
 
[ID] [int] IDENTITY (11NOT NULL ,
 
[unqValue] [uniqueidentifier] NOT NULL ,
 
[intValue] [int] NOT NULL 
ON [PRIMARY]
GO

ALTER TABLE [dbo].[tabTest] WITH NOCHECK ADD 
 
CONSTRAINT [PK_tabTest] PRIMARY KEY  CLUSTERED 
 (
  
[ID]
 )  
ON [PRIMARY] 
GO

ALTER TABLE [dbo].[tabTest] ADD 
 
CONSTRAINT [DF_tabTest_unqValue] DEFAULT (newid()) FOR [unqValue]
GO

CREATE  INDEX [IX_tabTest_unqValue] ON [dbo].[tabTest]([unqValue]ON [PRIMARY]
GO

declare @i int
declare @v int

set @i=0
while @i<10000
begin
    
set @v=rand()*1000    
    
insert into tabTest ([intValue]values (@v)
    
set @i=@i+1
end

然后我们执行两个查询并查看执行计划,如图:(在查询分析器的查询菜单中可以打开查询计划,同时图上第一个查询的GUID是我从数据库中找的,大家做实验的时候可以根据自己数据库中的值来定):



从图中可以看出,在第一个查询中,SQL Server使用了IX_tabTest_unqValue索引,根据箭头方向,计算机先在索引范围内找,找到后,使用Bookmark Lookup将索引节点映射到数据节点上,最后给出SELECT结果。在第二个查询中,系统直接遍历表给出结果,不过它使用了聚簇索引,为什么呢?不要忘了,聚簇索引的页节点就是数据节点!这样使用聚簇索引会更快一些(不受数据删除、更新留下的存储空洞的影响,直接遍历数据是要跳过这些空洞的)。

下面,我们在SQL Server中将ID字段的聚簇索引更改为非聚簇索引,然后再执行select * from tabTest,这回我们看到的执行计划变成了:

SQL Server没有使用任何索引,而是直接执行了Table Scan,因为只有这样,检索效率才是最高的。


三、聚簇索引与非聚簇索引的本质区别

现在可以讨论聚簇索引与非聚簇索引的本质区别了。正如本文最前面的两个图所示,聚簇索引的叶节点就是数据节点,而非聚簇索引的页节点仍然是索引检点,并保留一个链接指向对应数据块。

还是通过一道数学题来看看它们的区别吧:假设有一8000条记录的表,表中每条记录在磁盘上占用1000字节,如果在一个10字节长的字段上建立非聚簇索引主键,需要二叉树节点16000个(这16000个节点中有8000个叶节点,每个页节点都指向一个数据记录),这样数据将占用8000条×1000字节/8K字节=1000个页面;索引将占用16000个节点×10字节/8K字节=20个页面,共计1020个页面。

同样一张表,如果我们在对应字段上建立聚簇索引主键,由于聚簇索引的页节点就是数据节点,所以索引节点仅有8000个,占用10个页面,数据仍然占有1000个页面。

下面我们看看在执行插入操作时,非聚簇索引的主键为什么比聚簇索引主键要快。主键约束要求主键不能出现重复,那么SQL Server是怎么知道不出现重复的呢?唯一的方法就是检索。对于非聚簇索引,只需要检索20个页面中的16000个节点就知道是否有重复,因为所有主键键值在这16000个索引节点中都包含了。但对于聚簇索引,索引节点仅仅包含了8000个中间节点,至于会不会出现重复必须检索另外1000个页数据节点才知道,那么相当于检索10+1000=1010个页面才知道是否有重复。所以聚簇索引主键的插入速度要比非聚簇索引主键的插入速度慢很多。

让我们再来看看数据检索的效率,如果对上述两表进行检索,在使用索引的情况下(有些时候SQL Server执行计划会选择不使用索引,不过我们这里姑且假设一定使用索引),对于聚簇索引检索,我们可能会访问10个索引页面外加1000个数据页面得到结果(实际情况要比这个好),而对于非聚簇索引,系统会从20个页面中找到符合条件的节点,再映射到1000个数据页面上(这也是最糟糕的情况),比较一下,一个访问了1010个页面而另一个访问了1020个页面,可见检索效率差异并不是很大。所以不管非聚簇索引也好还是聚簇索引也好,都适合排序,聚簇索引仅仅比非聚簇索引快一点。


结语

好了,写了半天,手都累了。关于聚簇索引与非聚簇索引效率问题的实验就不做了,感兴趣的话可以自己使用查询分析器对查询计划进行分析。SQL Server是一个很复杂的系统,尤其是索引以及查询优化技术,Oracle就更复杂了。了解索引以及查询背后的事情不是什么坏事,它可以帮助我们更为深刻的了解我们的系统。

posted on 2004-07-20 10:31 吕震宇 阅读(11595) 评论(37)  编辑 收藏 所属分类: 数据库技术

评论

#1楼  2004-07-20 12:37 progame [未注册用户]
非聚簇对于更新肯定是有优势的
而它在检索的性能损失也不会太大

所以能不用聚簇当然是最好的了
但是如果使用\order by的话 
聚簇的优势也应该是很明显的

楼主可以测试一下这方面的数据
  回复  引用    

#2楼  2004-07-20 12:41 progame [未注册用户]
楼主的随笔中第二条论述说
非聚簇索引在排序上不输给聚簇索引多少

可是我记得,在数据库查询优化中有这样一个原则:
尽量避免在sql语句中使用order by

那么对于聚簇索引的话,我不需要order by,但我却得到了已经排序的结果,这其中的性能差异又有多大呢?
  回复  引用    

#3楼  2004-07-20 14:43 吕震宇      
“对于聚簇索引的话,我不需要order by,但我却得到了已经排序的结果”对于这句话我想未必。微软从来没有保证过使用聚簇索引的查询一定按照聚簇索引的顺序。不要忘了,SQL Server支持文件组,当一个数据库表跨两个文件甚至更多文件时,你觉得结果会不会按聚簇索引顺序输出呢?

  回复  引用  查看    

#4楼  2004-07-20 15:28 吕震宇      
还有一点在文中忘提到了,那就是复合查询。比如SELECT * FROM tabTest WHERE ID<100 AND unqValue >=...,检索条件涉及了ID与unqValue两个字段,那么如何利用索引呢?先过滤unqValue还是先过滤ID?非聚簇索引能够起到什么效果?所有这些就需要根据统计信息(数据密度、数据分布等)进行估算了。到那个时候,有可能非聚簇索引带来的效率提升比聚簇索引还要高。
  回复  引用  查看    

#5楼  2005-01-27 13:34 hhh [未注册用户]
关于: 三、聚簇索引与非聚簇索引的本质区别
执行插入操作时
对于非聚簇索引,只需要检索20个页面中的16000个节点就知道是否有重复
但对于聚簇索引,索引节点仅仅包含了8000个中间节点,至于会不会出现重复必须检索另外8000个页数据节点才知道,那么相当于检索10+1000=1010个页面才知道是否有重复。

这段不懂,前面不是说“聚簇索引的叶节点就是数据节点”,怎么现在反倒聚簇索引还必须检索另外8000个页呢?
  回复  引用    

#6楼 [楼主] 2005-01-28 13:34 吕震宇      
@hhh

对不起,我文章中的数字写错了。应当是“至于会不会出现重复必须检索另外1000个页数据节点才知道”。因为聚簇索引的页节点是数据节点。要想知道是否有重复,只有检索页节点才知道。所以聚簇索引的中间节点占10个页面,数据节点占1000个页面,共1010个页面。
  回复  引用  查看    

#7楼  2005-01-31 11:40 hhh [未注册用户]
我想了解的是,为什么
"对于非聚簇索引,只需要检索20个页面中的16000个节点就知道是否有重复,因为所有主键键值在这16000个索引节点中都包含了。但对于聚簇索引,索引节点仅仅包含了8000个中间节点,至于会不会出现重复必须检索另外1000个页数据节点才知道"

请问,聚簇索引不包含所有的主键键值吗?包含8000个中间节点有什么意义呢
  回复  引用    

#8楼 [楼主] 2005-02-01 15:21 吕震宇      
@hhh

其实要想实际计算出访问多少个页面是很困难的事情,所以只能比喻一下。究竟访问多少个页面是个未知数。

记得当时学FOXBASE时,老师说,你可以将索引文件认为就是一张表,只是这张表中仅包含的索引关键字的值以及记录号两列。关于这点,可以参考http://www2.cnblogs.com/zhenyulu/articles/28418.html,《从Visual FoxPro中的记录号与逻辑删除谈起...》。比如说,我要找学号为100的记录是否存在于表中,我们不必去访问表,仅仅访问一下索引文件就行了。磁盘IO将大大减少。SQL Server的索引道理是一样的。

由于非聚簇索引中包含了所有主键的值(也叫做索引覆盖查询),所以当我们要找学号是100的人是否在表中,我们没有必要去访问数据页面,仅仅访问索引页面就OK了。因为非聚簇索引的索引页面包含了所有表中关键字段的值。

但对于聚簇索引就不一样了,要想知道学号为100的学生是否在数据库中,必须访问数据页面才行,因为聚簇索引的叶节点是数据节点。这样IO访问两就增大了不少。

在本文开始的两张图中,如果问Ota这个人是否在数据库中,你找找试试,看看哪个需要访问数据页面,哪个不需要,再算一下哪个的IO访问量会大一些。
  回复  引用  查看    

#9楼  2005-02-02 08:21 hhh [未注册用户]
忽然茅塞顿开,我明白了,楼主真强,了解的如此深入,而且对于我们这种初级问题还回答这么细致,不顶不行啊:)
  回复  引用    

大家可以看看B-Tree,234Tree,理解后继续发言[从数据结构了解本质]
  回复  引用    

#11楼  2005-06-09 13:15 dragonpro      
我一定要搞得清清楚楚

非聚集索引在定位数据时不会依靠主键吧
  回复  引用  查看    

我只能向您说声谢谢!
以后能否多讲些关于DAO.NET和SQL SERVER
  回复  引用    

我只能向您说声谢谢!您真的好极了。
以后能否多讲些关于ADO.NET和SQL SERVER
  回复  引用    

#14楼  2005-06-19 04:27 wuw [未注册用户]
完全不懂B+树,完全不懂聚簇索引为什么放在树上。

比较中完全忽略了索引的基本结构——树,仅仅把他们当作两个顺序的集合,真是误人子弟。
  回复  引用    

#15楼  2005-06-19 04:48 wuw [未注册用户]
“现在我们要从一个有8000条记录的表中检索符合某个条件的记录,如果没有索引的话,我们可能需要遍历8000条×1000字节/8K字节=1000个页面才能够找到结果。如果在检索字段上有上述索引的话,那么我们可以在8000条×10字节/8K字节=10个页面中就检索到满足条件的索引块”

假设每100多个索引为一组,那么顺着B+树搜索8000个记录中的一个只需要两次取得索引组,即使他们都在不同磁盘块上也只需要两次读磁盘。而楼主竟计算出10次。由于楼主完全忽略b+树结构,所以那些比较完全是胡乱解释。
  回复  引用    

对楼主的水平有很大的怀疑!!!


记得当时学FOXBASE时,老师说,你可以将索引文件认为就是一张表,只是这张表中仅包含的索引关键字的值以及记录号两列。关于这点,可以参考http://www2.cnblogs.com/zhenyulu/articles/28418.html,《从Visual FoxPro中的记录号与逻辑删除谈起...》。比如说,我要找学号为100的记录是否存在于表中,我们不必去访问表,仅仅访问一下索引文件就行了。磁盘IO将大大减少。SQL Server的索引道理是一样的。

由于非聚簇索引中包含了所有主键的值(也叫做索引覆盖查询),所以当我们要找学号是100的人是否在表中,我们没有必要去访问数据页面,仅仅访问索引页面就OK了。因为非聚簇索引的索引页面包含了所有表中关键字段的值。

但对于聚簇索引就不一样了,要想知道学号为100的学生是否在数据库中,必须访问数据页面才行,因为聚簇索引的叶节点是数据节点。这样IO访问两就增大了不少。


1、如果对于聚簇索引,要想知道学号为100的学生是否在数据库中,就必须要访问数据页面才行的话。那么请问聚簇索引中是否记录着学号“100”和这条对应记录的地址呢?那么既然聚簇索引中都已经记录着学号“100”了,那为什么还要去访问数据页面才能知道是否有这个学生在数据库中呢?真是乱弹琴!

2、“由于非聚簇索引中包含了所有主键的值(也叫做索引覆盖查询)”!索引覆盖查询是这个意思吗!?严重吐血!!!



  回复  引用    

#17楼  2005-07-20 19:17 求索者 [未注册用户]
首先感谢楼主无私的把自己的见解写出来,给后学者参考。
我感到困惑的内容其实与hhh提的内容差不多,只是他豁然开朗了,我还没明白。
假如利用聚簇索引检索,每次还要到另外的1000个页中去检索一遍,那效率跟不建索引有什么区别啊,数据库还辛辛苦苦将物理顺序按照聚簇索引排序了一把,难道是数据库设计者脑袋出了问题。
我觉得“索引的叶节点就是数据节点。而非聚簇索引的叶节点仍然是索引节点,只不过有一个指针指向对应的数据块”这句话这样理解是否更好一点啊。因为数据库中的记录已经按聚簇索引排好了序,所以聚簇索引叶节点只需要记录数据,至于它在数据库中的实际位置,可以按记录序号*记录长度+文件头地址,就如你在《从Visual FoxPro中的记录号与逻辑删除谈起...》中说的那样。而非聚簇索引就必须再加上数据对应地址才能真正确定位置。
  回复  引用    

#18楼 [楼主] 2005-07-23 18:01 吕震宇      
@一个拙劣的程序员

关于你提出的第一个问题,你可以从本文第二个图中找找Ota是否在数据库中就知道是否要访问数据页面了。

关于你的第二个问题,我想是我的笔误,这可以我从后面的话推出“因为非聚簇索引的索引页面包含了所有表中关键字段的值”。我这里将关键字段误写成了主键,很严重的错误。这里的关键字(Key Words)指要查询的字段。
  回复  引用  查看    

#19楼  2005-07-25 17:29 两极狼 [未注册用户]
因为对uniqueidentifier来说,当数据量很大时,对它的查询将变得很慢,这时该如何实现对它的优化呢???


望高手指点
  回复  引用    

#20楼  2005-12-01 03:52 三水 [未注册用户]
其实楼主解释的很不错了,简单易懂,如果大家学了数据结构很快就能理解大概意思,自己再加工就行了,不必对楼主的笔误纠缠不休~
  回复  引用    

严重支持吕老师~~
您写得'相当'之好啊:)
呵,套用了宋丹丹的'相当'
一词
  回复  引用    

#22楼  2006-03-23 03:52 素食 [未注册用户]
如果对于聚簇索引,要想知道学号为100的学生是否在数据库中,就必须要访问数据页面才行的话。那么请问聚簇索引中是否记录着学号“100”和这条对应记录的地址呢?那么既然聚簇索引中都已经记录着学号“100”了,那为什么还要去访问数据页面才能知道是否有这个学生在数据库中呢?真是乱弹琴!

答: [记录着学号“100”]这句话要格外的留意 ,因为混淆了2个概念 ,其一fox溪流数据存储方式中的行号对应于目前大型关系型数据库的oid (这个东西在sql server里被微软给藏起来了 也很少有人知道,但是其他很多尤其开源的数据库都有这个东西的)
[聚簇索引中都已经记录着学号“100”]这句话重点是 '聚簇索引'是文件 数据页面 是runtime时候用于访问聚簇索引文件的数据部分当然了 这部分内容多的时候也会在内存和磁盘上同时存在

说实话 我特别想和微软说的就是"把oid还给我好么" 因为10多年前我fox ,5年前我posetgres都有这东西啊,不过没办法估计他们不会满足我这个过分的要求的 It's Unsafe 我替他们回答

  回复  引用    

#23楼  2006-05-23 10:46 小刀 [未注册用户]
写的这么好还要被人说,唉~~~

吕老师也是人自然有疏忽的地方,而且SQL Server又不是他设计的,有点小错

误也是正常的,谈不上“误人子弟”这么严重。

我觉得技术交流应该心平气和,以切磋、相互提高为目的,正说n楼所说:“不必对楼主的笔误纠缠不休”
  回复  引用    

#24楼  2006-07-23 23:30 SSWSD [未注册用户]
"“现在我们要从一个有8000条记录的表中检索符合某个条件的记录,如果没有索引的话,我们可能需要遍历8000条×1000字节/8K字节=1000个页面才能够找到结果。如果在检索字段上有上述索引的话,那么我们可以在8000条×10字节/8K字节=10个页面中就检索到满足条件的索引块”

假设每100多个索引为一组,那么顺着B+树搜索8000个记录中的一个只需要两次取得索引组,即使他们都在不同磁盘块上也只需要两次读磁盘。而楼主竟计算出10次。由于楼主完全忽略b+树结构,所以那些比较完全是胡乱解释。"
楼住年怎么解释啊


  回复  引用    

#25楼  2006-08-01 09:50 姓名 [未注册用户]
@SSWSD
这是一个大问题,既然谈到了B+tree索引,怎么能不考虑b+的基本查询原理?怎么会是全扫描?就是顺序表也可以用二分法,lnn/ln2的次数就可以了
  回复  引用    

#26楼  2006-08-11 16:15 wonder      
个人感觉设不设索引...设什么索引...
应该要看实际的情况而定
  回复  引用  查看    

#27楼  2006-08-11 16:16 wonder      
建议大家看看这片文章:
http://www.cnblogs.com/fanrsh/archive/2006/06/27/436618.html
  回复  引用  查看    

#28楼  2007-05-11 16:09 java猪 [未注册用户]
我看楼主写错了吧

都是主键索引,聚簇索引为什么要去查询别的数据页?聚簇索引的节点不就是主键的物理位置么?

楼主把非聚簇索引的情况下搜索关键字是主键,聚簇索引情况下搜索关键字不是主键来进行比较了。


  回复  引用    

#29楼  2007-06-25 10:03 轻轻松松      
楼上的对数据库看来不太清楚,呵呵!

楼主讲的没有太大问题,个人意见
  回复  引用  查看    

呵呵,我也来评一下,切磋切磋
  回复  引用    

这么说吧,实际上那个b树的理解是太抽象了,用脑袋去理解硬盘上的二进制数据是怎么样排列的??
除非是sqlserver的开发工程师才比较清楚.
对于聚集索引和非聚集索引,姑且就这么看吧.
1.所谓索引就是在其它地方保存了一些键值对,键即索引列的值,值即地址指针.并且是按顺序排列的.

无论聚集非聚集都是这样的,这样要要找id=..,id>30 and id <100,oracle by id,group by xxid(该列引用了别的表),就很方便了,

因为存放索引是按顺序存放的,物理数据也是按顺序存放的,找起来当然方便了.但是非聚集索引的性能可能会稍差点,因为物理数据的顺序和索引的顺序是不一致

的,而聚集索引正好相反,比如对id列建聚集索引,那么物理数据的顺序是按id列的值排列,聚集索引中也是按id列的值排列,这时如果再对addtime列建非聚集索引

呢,那么会重新开辟一块存非聚集索引的空间,并按addtime的值的顺序进行索引保存.如果这是你找的是某个范围的addtime的值,在索引存放区匹配到的地址是不连贯的,按这些地址再去找实际的数据行当然就比较慢的,但是想象一下,如果找某个id范围的值,那么因为是id是聚集索引所以数据行是按id值顺序排列的,索引区也是按id列排列的,索引匹配到的一系列地址就是比较连续的(理想情况是这样)

重新申明一点,聚集和非聚集索引都是有单独一块索引存放空间的,不然一个表如果很大,是很难想象的,并且都是把索引列的值和该行地址拷贝过去的,你可以想象一下,找id=100的数据行,如果索引区没有100这个值,又如何去匹配?对于大表来说,即使数据行是按聚集列的值的顺序存放的,要直接在里面找也是很慢的,给你一本新华字典叫你直接翻到h字母开始的那页看快不快?还是直接找页码比较快

  回复  引用    

2.聚集索引和非聚集索引的区别?
聚集索引中的顺序也就是数据行的实际排列顺序,每次增删改等都可能进行数据行移动,所谓聚集也就是按顺序的意思,索引列值大小相近的物理数据行排在一起.
对于聚集索引请不要建在将会频繁修改的列上,因为数据行是按列值大小排序的,因此可能会引起数据行整行移动.

非聚集则没有这些特点,它和数据行的物理排列顺序不相干,它只不过是物理数据的另一种"目录"罢了,就象字典除了拼音检索还是有其它好几种检索方式

为什么一个表只能有一个聚集索引,因为数据行的物理排序只能有一种.但是逻辑排序却可以很多,在其它地方搞几个"目录"这就是逻辑排序,所以从这点上看我想连初中生都可以知道聚集索引大部分情况是比非聚集索引快的,因为有先天优势呢,ok?
  回复  引用    

#33楼  2008-07-09 20:53 fdsaf [未注册用户]
说了半天,还是没没明白,楼主你只要告诉我怎么查询数据最快就行。
  回复  引用    

吕兄:
呵呵,我抱着学习交流的心态来看的。
很多地方讲解的比较详细。但是
有的地方有异议,
1.你最后的结论是“聚集索引比非聚集索引快”,
这个在查询里,是不一定的,要看实际的情况,记得CSDN上以前有的帖子就是讨论这个问题的。自己后来也看了很多资料,包括帮助文档,所以这个结论是不准确的。
2.树的节点数目计算有疑惑:
8000个页节点,树的节点数目应该在2的n次方到2的n-1次方之间(n为树的高度)
3.通过非聚集索引查找数据的过程里用到了聚集索引的节点信息,聚集索引的叶子节点信息里包含数据在磁盘上的位置信息,这个资料上可以查询的到。

以上都是观点仅仅作交流~~虚心向大家请教,一起学习进步!
  回复  引用    

#35楼  2008-08-04 14:07 eract.yq [未注册用户]
博主说得很有道理,让我对sql的索引情况有了更多学习,谢谢提供。不过有的时候用sql最大的问题,就是不知道其具体是怎么运行的。像这条语句,select * from a, b where A条件 and B条件,他的执行过程是不是这样的,先将a,b进行自然连接,然后在根据A条件筛选掉一部分,有一个结果表产生,然后在根据B条件再在这个结果表中筛选掉一部分,得出结果?哎,博主对这个问题有何见解吗?
  回复  引用    

贱货
  回复  引用    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2005-01-28 13:46 编辑过


相关链接: