簡體   English   中英

為什么NonClustered索引掃描比聚簇索引掃描更快?

[英]Why NonClustered index scan faster than Clustered Index scan?

據我所知,堆表是沒有聚簇索引的表,沒有物理順序。 我有一個堆棧表“掃描”有120k行,我使用這個選擇:

SELECT id FROM scan

如果我為列“id”創建一個非聚集索引,我會得到223個物理讀取 如果我刪除非聚集索引並更改表以使“id”成為我的主鍵(以及我的聚簇索引),我將獲得515個物理讀取

如果聚集索引表是這樣的圖片:

在此輸入圖像描述

為什么Clustered Index Scans像表掃描一樣工作? (或者在檢索所有行的情況下更糟)。 為什么它不使用具有較少塊的“聚簇索引表”並且已經具有我需要的ID?

SQL Server索引是b樹。 非聚集索引僅包含索引列,b樹的葉節點是指向適當數據頁的指針。 聚簇索引是不同的:它的葉節點是數據頁本身,聚簇索引的b樹成為表本身的后備存儲; 堆不再存在於表中。

您的非聚集索引包含一個可能是整數列。 這是一個小而緊湊的索引。 select id from scan查詢select id from scan具有覆蓋索引 :只需檢查索引就可以滿足查詢,這就是正在發生的事情。 但是,如果您的查詢包含不在索引中的列,假設優化程序選擇使用非聚集索引,則需要額外的查找來從聚簇索引或堆中獲取所需的數據頁。

要了解發生了什么,您需要檢查優化器選擇的執行計划:

聚簇索引通常與堆中的相同數據一樣大(假設頁面完整性相同)。 由於額外的B樹級別,它應該使用比堆更多的讀取。

CI不能小於堆。 我不明白為什么你會這么想。 分區的大部分大小(無論是堆還是樹)都在數據中。

請注意,較少的物理讀取不一定轉化為查詢更快。 隨機IO可能比順序IO慢100倍。

何時使用聚集索引 -

查詢注意事項:
1)使用BETWEEN,>,> =,<和<= 2等運算符返回一系列值。返回大的結果集
3)使用JOIN子句; 通常這些是外鍵列
4)使用ORDER BY或GROUP BY子句。 ORDER BY或GROUP BY子句中指定的列的索引可能不需要數據庫引擎對數據進行排序,因為行已經排序。 這提高了查詢性能。

列注意事項:考慮具有以下一個或多個屬性的列:1)是唯一的或包含許多不同的值2)定義為IDENTITY,因為該列在表中保證是唯一的3)經常用於對從中檢索的數據進行排序一張桌子

對於以下屬性,聚簇索引不是一個好的選擇:1)經常更改的列2)寬鍵

何時使用非聚集索引 -

查詢注意事項:
1)使用JOIN或GROUP BY子句。 在連接和分組操作中涉及的列上創建多個非聚簇索引,並在任何外鍵列上創建聚簇索引。
2)不返回大型結果集的查詢
3)包含經常涉及查詢的搜索條件的列,例如WHERE子句,返回完全匹配

欄目注意事項
考慮具有以下一個或多個屬性的列:
1)覆蓋查詢。 有關更多信息,請參閱包含列的索引
2)如果聚集索引用於其他列,則有許多不同的值,例如姓氏和名字的組合
3)經常用於對從表中檢索的數據進行排序

數據庫考慮因素:
1)具有較低更新要求的數據庫或表,但是大量數據可以從許多非聚簇索引中受益,以提高查詢性能。
2)包含大量更新表的聯機事務處理應用程序和數據庫應避免過度索引。 此外,索引應該是窄的,即盡可能少的列。

試試跑步

DBCC DROPCLEANBUFFERS

在查詢之前......

如果你真的想比較它們。 優化查詢時,物理讀取與邏輯讀取的含義不同

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM