2012-04-15 200 views
5

我有一個Oracle背景,每個表使用「索引組織表」(IOT)在Oracle中聽起來不合理,我從來沒有看到過這種情況。在SQL Server中,我工作的每個數據庫在每個表上都有一個聚簇索引,這與IOT(概念上)相同。集羣索引SQL Server

這是爲什麼?在任何地方使用聚簇索引是否有任何理由?在我看來,只有少數情況下他們纔會好。

感謝

+4

以下是有關[DBA-SE](http://dba.stackexchange.com/)的相關問題,其中包含一些信息和一些可供您閱讀的鏈接。 [堆或非聚簇索引上的非聚簇索引的性能](http://dba.stackexchange.com/questions/9829/performance-of-non-clustered-indexes-on-heaps-vs-clustered-indexes) – 2012-04-15 12:41:50

+4

可能是a問題最好由熟悉Oracle和SQL Server的人回答。 [dba.se]可能是更好的選擇。 – 2012-04-15 13:33:04

+1

另外,建議您將此問題移至dba.se.它有兩條評論和一條來自DBA.SAE的常規答案(純粹是巧合),沒有任何其他海報實際上挑選聚集索引和IOT實際上有顯着差異。 – ConcernedOfTunbridgeWells 2012-04-15 16:20:22

回答

2

如果沒有聚簇索引,您的表被組織爲一個堆。這意味着插入的每一行都被添加到表格末尾的數據頁面中。同樣,當行更新時,如果更新的數據比以前更大,它們將移動到表的末尾的數據頁面。

當這是好事,沒有一個聚集索引

如果您有需要以最快的速度插入一個表格,但可以犧牲更新和讀取速度,那麼沒有一個聚集索引可以用於工作您。一個例子是如果你有一個被用作隊列的表,例如,大量的插入後來才被讀取並移動到不同的表中。

聚集索引

聚簇索引基於聚集索引中的列在表中組織數據。如果你把錯誤的東西聚集在一起,例如一個獨特的標識符,這可能會減慢速度(見下文)。

只要您的聚集索引是最常用於搜索的值,並且它是獨一無二的並且越來越多,您就可以從聚集索引中獲得驚人的性能優勢。例如,如果您有一個名爲USERS的表,您通常根據USER_ID查找用戶數據,則在USER_ID上進行聚類可以加快所有這些查找的性能。這簡單地減少了需要讀取以獲取數據的數據頁的數量。

如果聚簇索引中的鍵太多,這也會減慢速度。

聚簇索引的一般規則:

不聚集在任何varchar列上。

對INT IDENTITY列進行聚類通常是最好的。

關於您常用搜索的羣集。在UniqueIdentifiers

隨着指數uniqueidentifiers

聚類,他們是非常低效的,因爲沒有自然的排序順序。基於索引的b-tree結構,當使用uniqueidentifiers時,最終會產生極其分散的索引。重建或重組後,它們仍然非常分散。所以你最終會得到一個較慢的索引,由於存在碎片,最終會導致在內存和磁盤上非常龐大。同樣,在插入uniqueidentifier時,您更可能最終在索引上進行頁面拆分,從而減慢插入速度。通常,uniqueidentifiers對於索引是個壞消息。

摘要

我的建議是,每個表上應該有一個聚集索引,除非有很好的理由不要(即表作爲隊列功能)。

+0

這證實了我對聚簇索引的理解。我可以理解在有限行數的查找表上有索引。適合賬單。基本上,對於不斷增長的事實表來說堆積,並且插入時自然排序。讓我一直困惑的就是你在「UniqueIdentifiers上的集羣」中描述的那個,我繼承了一個數據庫,其中一個數據庫在2B行表中增長了!它對我來說從來沒有意義!最重要的是,它有一個自動化的工作來重建它。謝謝,許多事情現在開始有意義。 – Younes 2012-04-15 18:42:04

0

我們使用主鍵在關係數據庫和一般的關係,通過這些主鍵建立。大多數人習慣於將第一個字段命名爲TableID並將其作爲主鍵。當您在查詢中加入兩個或多個表時,如果使用聚簇索引,您將獲得最快的結果。

1

我不知道爲什麼大多數時候你更喜歡堆積聚集索引。使用集羣,您可以免費獲得您選擇的一個索引。大多數情況下,這是主鍵(無論如何,您可能要強制執行!)。

堆主要針對特殊情況。

6

聚集索引與索引組織表不完全相同。使用IOT,每個字段都必須參與IOT密鑰。 SQL Server上的聚集索引不必是唯一的,並且不必是主鍵。

集羣索引廣泛用於SQL Server,因爲幾乎總是有一些自然排序使常用查詢更高效。甲骨文的物聯網帶着更多的包袱,所以它們並沒有那麼有用,儘管它們可能更有用,然後他們通常被稱爲。

從歷史上看,真正舊版本的SQL Server pre 6.5或7.0 IIRC不支持行級鎖定,只能鎖定在表或頁級別。通常會使用聚簇索引來確保寫入分散在表的物理存儲周圍,以最大限度地減少對頁面鎖的爭用。但是,SQL Server 6在幾年前就已經得到支持,所以具有此問題的應用程序將僅限於罕見的遺留系統。

+0

我通常不介意維度表(小表)上的聚集索引。但事實上,我不確定這是一個好主意,它會減緩加載速度和全面掃描。幾乎在所有情況下,自然順序都是基於時間的,通常是數據加載順序。 – Younes 2012-04-15 18:24:46

+1

@Younes - 由於大多數查詢都涉及表掃描,聚集索引在事實數據表上並不是很實用。也許對於不支持分區的版本(例如2012 B.I.版),您可能希望在日期或時間段列上使用聚簇索引,以最大程度地減少加載或歸檔操作時的I/O。具有日期範圍的查詢也可以使用聚集索引通過使用範圍掃描操作來減少I/O。 – ConcernedOfTunbridgeWells 2012-04-15 19:00:24