2010-10-30 60 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

相關問題