2010-10-30 63 views
2

簇索引的中间体叶被顺序(下一个,上一个)以便更快地访问(中间节点之间)[1],等:如何使用聚簇索引的中间叶子之间的顺序遍历?

alt text

如何使用[2]该访问链接的?
为什么需要?

[1]
聚集索引结构
http://msdn.microsoft.com/en-us/library/ms177443.aspx
[2]
集群表VS堆表
http://www.mssqltips.com/tip.asp?tip=1254

更新: 随访回答者问题:

+0

这不是我投票你的每一个问题。有人跟踪你,每次都在揍你。 – PerformanceDBA 2010-10-30 08:41:18

+0

谢谢,这是一个知道,因为我开始怀疑的救济。我明白,当一位古茹不能通过复制和粘贴谷歌结果来说任何事情时,错误是坏的问题或在坏提问者 – 2010-10-30 09:01:58

+0

呃,没有。这是无稽之谈,原因很多。首先,网络充满了垃圾,而不是严重的技术信息。二,大师可以直接回答,而不必参考甚至好的文本。尽管他们可能不希望每次都输入大量的信息。 – PerformanceDBA 2010-10-30 09:14:58

回答

1

聚簇索引(而不是非聚簇索引)可用于范围查询。你知道那是什么吗?在范围查询期间确定合格的行时,B-Tree的水平遍历可以提高导航CI的速度。

从更一般的意义上讲,如果服务器缓存太小,并且CI页面被分页出去,那么当任何查询(不仅是范围查询)需要在下行时或下行时通过下一页一个CI,它可以通过单个磁盘访问获取页面,因为页面通过指针链接;即。它避免了向上走一级找到下一页)。只是其中一个 CIs比NCI快很多的原因;他们更加强化,因为NCI依赖于他们(今天的另一个问题)。

该图有错误(包含错误信息),或者更准确地说,它是一个描述性的,非技术性的图,从非技术公司:

  1. 中间水平有指向下一级页面的单指针(不是多指针)。

  2. 叶级是数据行。没有指向行的指针(在中间OR叶级别)。

  3. 索引页面不像文本和图像页面。每个索引页包含数百个索引B-Tree条目。

  4. 根页面的不同之处仅在于第一个条目是索引的单根;它包含数百个当然是第二个层次的条目,也可以是第三级,等

是有原因的技术人员绘制和使用,技术图纸:除其他外,它避免误解和混乱。没有问题的Diagram I Made for You

回应马丁·史密斯的帖子

一个。我:聚簇索引(而不是非群集索引)可以被用于范围查询

MS:不正确:非聚集索引可以使用,只要非常清楚用于范围查询作为非群集指数正在覆盖。

看起来您明白涵盖查询,但您不明白范围查询。请阅读它。不幸的是,它被命名为“查询”,但实际上它是所有SQL供应商提供的性能技术。假设你有一个真正的关系表,这意味着一个复合关键字,例如。发票PK是(CustomerId,InvoiceNo)[not InvoiceId]。随后的查询,如:

SELECT * FROM Invoice WHERE CustomerId = @CustomerId 

将定位B树的ClusteredIndex 的一次,以找到客户编号拳头发票。然后,它将跟随LeafLevel(数据行)的PageChain获取CustomerId的第二个和后续发票。查询不再使用B-Tree。范围查询在遇到第一个CustomerId> 1的发票时结束。

这只是可能带有一个ClusteredIndex,在一个物理结构中,B树与数据结合。

NonClusteredIndex-plus-Data(这是一个堆或一个ClusteredIndex)在物理上是不可能的。这是为什么范围查询不能支持NCI的。即使你有一个NCI(CustomerId,InvoiceNo),数据行也不会按照这个顺序;他们将在堆中按时间顺序排列;因此使用该NCI的查询将提取每个NCI条目的一行。

b。 Me:CIs比NCI快得多;他们更增强,因为NCI取决于他们

MS:聚簇索引的B树结构是从非聚集索引没有什么不同。 CI没有增强或以某种方式具有不同的和优越的结构...

那里没有争执。你只是误解了我,速度,我在谈论整个表(NonClusteredIndices不能独立存在)。让我澄清一下:给定相同的密钥,一个ClusteredIndex(包含数据)总是比NonClusteredIndex-plus-Heap快得多。对单个数据存储结构(CI)进行导航,维护,创建和删除操作显然比对两个数据存储结构(NCI + Heap)的操作要快得多。

它在物理上不能够使2点的DS快于一个DS(使用相同的密钥假设。)

℃。不值得回应。看来你并没有意识到我的评论与不正确的图表有关。换句话说,你的意见(和证明)是相当正确。

+0

感谢您对我的屠宰技术图。尽管我宁愿选择主流的公开文档/参考文献。我每天都看着它,但现在我紧急地偏离阅读您的EAV回复http://stackoverflow.com/questions/4011956/multiple-fixed-tables-vs-flexible-abstract-tables/4013207#4013207 – 2010-10-30 10:35:19

+0

也许你错过了上面的最后一段。如果mainstrean文档足够好,人们不会浪费时间创建技术上准确的文档。也许你错过了这样一个观点,即你发布的主流文件导致混乱;这是什么导致你发布;这正是我所回答的;这样做时不得不离开这种文件。问题在于有些人把MS当作福音,它不是。我很乐意回答具体问题;我不会浪费时间回应MS垃圾山。 – PerformanceDBA 2010-10-30 20:58:11

+0

嗨,我以后会提问,可能不会在这个委员会。我转移到sqlservercentral.com/Forums/Forum373-1.aspx再次感谢您的时间! 我已经在这里超过了十几个禁令,没有任何警告,对于这样的,令人恼怒的当地大师,问题),或者问为什么我之前被禁止(并且仍然被禁止在meta.paldoverlow.com) – 2010-11-01 08:19:21

1

首先,正如PerfomanceDBA所指出的,为了理解SQL Server内部,最好使用Sybase文档和术语。

其次,很好地解释了在哪里,为什么和水平如何中间连续横贯在[1]解释:

  • “预读中一键有序扫描

    使用按键排序扫描时,引擎会使用存储在中间索引页面中叶级以上1级的信息来安排包含已找到密钥的页面的串行预读,如果例如对所有从1到100的密钥进行请求,将首先读取密钥1的叶页上方的索引页(在遍历叶页的方式上);但是,不是简单地y从第1页到第100页依次读取每个页面页面,引擎扫描中间页面页面并构建必须读取的页面列表以获取第1页到第100页,然后按键顺序计划所有阅读内容 - 此外,引擎将识别页面是否连续,并执行单次读取以在单个操作中检索相邻页面,而不是多个较小的操作。由于非聚簇索引的叶子行包含指向群集/堆结构中数据行的指针,因此在扫描非聚簇索引时,使用类似的操作从基簇或堆中预取数据,当存储引擎读取非聚簇索引的叶时,它也开始为其指针已被检索的相应数据行调度异步读取。这使得引擎可以在完成非聚集索引扫描之前从底层集群/堆中有效地获取数据。

    在一个关键的有序扫描一个预读的导航看起来像下面这样:

alt text

[1]
乍得博伊德
MSSQLTips - SQL Server博客
分段工作站 - 停止#1 - 存储基础知识和访问方法 http://blogs.mssqltips.com/blogs/chadboyd/archive/2007/11/12/fragmentation-station-stop-1-storage-basics-and-access-methods.aspx

+0

+1这是正确的答案。中级页面链接是非常需要预读的。范围扫描(实际上是任何扫描)导航叶级链接链,永远不会回到中间级别。 – 2012-07-09 09:47:11

1

您在问题中的图表完全准确地代表Microsoft SQL Server中的索引。

为了解决PerformanceDBA答案的某些方面,我认为这些答案不正确或未得到充分解释。

“聚簇索引(而不是非群集索引)可以被用于范围查询”

不正确:非聚集索引可以使用,只要非常清楚用于范围查询作为非聚集索引正在覆盖。

“顺式比NCIS快得多;他们更增强,因为NCI取决于他们”

聚簇索引的B树结构是从非聚集索引没有什么不同。 CI没有增强,或者以某种方式具有不同的和优越的结构。如果任何NCI略有增强,它们并不总是具有NULL_BITMAP和“状态位B”字节,因此可能稍微更紧凑。

“中间级别有一个指向下一级页面的单指针(不是多指针)......没有指向行的指针(在中间OR叶级别)。“

USE tempdb 

IF OBJECT_ID('testing') IS NULL 
BEGIN 
    CREATE TABLE testing 
    (
    a INT IDENTITY(1,1) PRIMARY KEY CLUSTERED, 
    b INT NOT NULL, 
    c CHAR(4000) NOT NULL DEFAULT REPLICATE('c',4000), 
    d CHAR(4000) NOT NULL DEFAULT REPLICATE('d',4000) 
    ) 

    CREATE UNIQUE NONCLUSTERED INDEX ix ON testing (b) INCLUDE (d) 

    INSERT INTO testing (b) 
    SELECT TOP 3000 ROW_NUMBER() OVER (ORDER BY (SELECT 0)) 
    FROM sys.all_columns s1, sys.all_columns s2 
END 

IF OBJECT_ID('index_pages') IS NULL 
BEGIN 
CREATE TABLE index_pages 
(
PageFID TINYINT, 
PagePID INT, 
IAMFID TINYINT, 
IAMPID INT, 
ObjectID INT, 
IndexID TINYINT, 
PartitionNumber TINYINT, 
PartitionID BIGINT, 
iam_chain_type VARCHAR(30), 
PageType TINYINT, 
IndexLevel TINYINT, 
NextPageFID TINYINT, 
NextPagePID INT, 
PrevPageFID TINYINT, 
PrevPagePID INT, 
PRIMARY KEY (PageFID, PagePID) 
) 
END 
ELSE 
TRUNCATE TABLE index_pages 

INSERT INTO index_pages 
EXEC('DBCC IND(tempdb, testing, 2)') 

SELECT * 
FROM index_pages 
ORDER BY IndexLevel DESC 

你会看到,一级(中间级别)的页面具有由NextPagePIDPrevPagePID列表示水平指针。除了这些页面级指针每个索引项有一个指针指向一个页面如下图所示:

要查看此选项,请选择属于一级页面的PagePID s,然后查看Internals Viewer for SQL Server中的该页面,您将看到(如下所示)每个索引记录有它自己的向下页指针

在下面的屏幕截图中选择的特定单个记录中,可以看到它显示叶页1:186上的第一条记录的关键值为13或更高。

Internals Viewer

相关问题