簡體   English   中英

與非集群相比,外鍵列上的聚集索引是否可以提高聯接性能?

[英]Does clustered index on foreign key column increase join performance vs non-clustered?

在很多地方,建議在使用BETWEEN語句選擇行范圍時更好地利用聚集索引。 我猜想當我選擇使用外鍵字段進行聯接以使用該聚簇索引時,我猜想,由於行范圍被選擇,即使它們都具有相同的聚簇鍵值且未使用BETWEEN,聚簇也應會有所幫助。

考慮到我只關心一個帶有join的選擇,而不關心其他任何事情,我的猜測是否錯了?

絕對討論這種類型的問題不是很有用。

總是一個個案的情況!

本質上, 通過聚集索引的訪問節省了一個間接時間 ,周期。

假設在JOIN中使用的鍵是聚集索引的鍵,那么在單次讀取中[無論是來自索引查找還是來自掃描或部分掃描,都沒有關系],您將獲得整行(記錄)。

聚集索引的一個問題是,每個表只能獲得一個索引。 因此,您需要明智地使用它。 實際上,在某些情況下,由於INSERT開銷和碎片(取決於密鑰和新密鑰的順序等),根本不使用任何聚集索引甚至是更明智的選擇。

有時,人們可以獲得與聚集索引相同的好處,即覆蓋索引 ,即具有所需鍵序列的索引,然后是我們感興趣的列值。就像聚集索引一樣,覆蓋索引不會需要間接訪問基礎表。 實際上,覆蓋索引可能比聚簇索引稍微有效,因為它較小。
但是,就像聚簇索引一樣,除了存儲開銷外,在INSERT(和DELETE或UPDATE)查詢期間,與任何其他索引相關聯的性能成本也存在。

而且,是的,如其他答案所示,用於聚集索引的密鑰的“外鍵性”與索引的性能完全無關。 FK是旨在簡化數據庫完整性維護的約束,但是基礎字段(列)與表中的任何其他字段一樣。

要對索引結構做出明智的決策,需要

  • 了解各種索引類型(和堆)的工作方式
    (順便說一句,這在SQL實現之間有所不同)
  • 對現有數據庫的統計資料有一個良好的印象:
    哪些是大表,哪些是關系,什么是關系的平均/最大基數,什么是數據庫的典型增長率等?
  • 對將要使用/查詢數據庫的方式有很好的了解

然后並且只有那時,人們才能對有興趣(或缺乏興趣)做出有根據的猜測,以得到給定的聚集索引。

我會問其他問題:將我的聚集索引放在外鍵列上只是為了加快單個JOIN的運行速度是否明智? 它可能有幫助,但是.....要付出代價!

對於每個操作,聚簇索引可使表更快。 是! 是的 有關背景信息,請參見Kim Tripp的出色著作《聚集索引辯論》 她還提到了聚集索引的主要標准:

  • 狹窄
  • 靜態的(永遠不變)
  • 獨特
  • 如果可能:不斷增加

INT IDENTITY完美地實現了這一點-GUID不能。 有關廣泛的背景信息,請參見GUID作為主鍵

為什么要縮小? 因為將聚簇鍵添加到同一表上每個非聚簇索引的每個索引頁(以便在需要時能夠實際查找數據行)。 您不想在群集鍵中包含VARCHAR(200)。

為什么獨特? 參見上文-群集鍵是SQL Server用於唯一查找數據行的項目和機制。 它必須是唯一的。 如果您選擇一個非唯一的群集密鑰,SQL Server本身將為您的密鑰添加一個4字節的唯一標識符。 注意這一點!

因此,這些就是我的標准-將您的集群鍵放在狹窄,穩定,獨特,希望不斷增加的列上。 如果您的外鍵列與之匹配-完美!

但是,在任何情況下,我都不會將我的群集密鑰放在一個寬的甚至是復合的外鍵上。 請記住:聚簇鍵的值將添加到該表上的每個非聚簇索引條目中! 如果您有10個非聚集索引,則表中有100'000行-一百萬個條目。 無論是4字節整數還是200字節VARCHAR-HUGE,這都將產生巨大的差異。 不僅在磁盤上-還在服務器內存中。 非常仔細地考慮如何創建聚集索引!

SQL Server可能需要添加唯一符-使情況變得更糟。 如果這些值會發生變化,則SQL Server必須在整個位置進行大量記賬和更新。

簡而言之:

  • 在外鍵上添加索引絕對是個好主意-始終做到!
  • 在創建該聚集索引時,我將非常小心。 首先,您只會得到一個聚簇索引,那么您將選擇哪種FK關系? 並且不要將聚類鍵放在寬且不斷變化的列上

FK列上的索引將對JOIN有所幫助,因為索引本身是有序的:聚集只是意味着磁盤(葉)上的數據是有序的,而不是B樹。

如果將其更改為覆蓋索引,則無關緊要的是群集的還是非群集的。 重要的是要有一個有用的索引。

這取決於數據庫的實現。

對於SQL Server,聚集索引是一種數據結構,其中數據存儲為頁面,並且有B樹並且存儲為單獨的數據結構。 獲得快速性能的原因是,您可以快速進入鏈的起點 ,並且范圍很容易遵循。

非聚集索引是一種數據結構,其中包含指向實際記錄的指針,並因此涉及不同的關注點。

請參閱有關聚簇索引結構的文檔。

索引與外鍵關系無關,但是由於“覆蓋”索引的概念,索引將有所幫助。 如果您的WHERE子句包含基於索引的約束。 它將能夠更快地生成返回的數據集。 那就是性能的來源。

如果在群集中順序選擇數據,通常可以提高性能。 而且,它完全取決於表(數據)的大小以及之間語句的條件。

暫無
暫無

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

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