簡體   English   中英

SQL Server聚簇索引 - 索引問題的順序

[英]SQL Server Clustered Index - Order of Index Question

我有一張像這樣的桌子:

keyA keyB data

keyA和keyB一起是唯一的,是我表的主鍵,並構成聚簇索引。

keyB有5個可能的值,但keyA的可能值不限。 keyB通常遞增。

例如,以下數據可以按兩種方式排序,具體取決於首先訂購的鍵列:

keyA keyB data
A    1    X
B    1    X
A    3    X
B    3    X
A    5    X
B    5    X
A    7    X
B    7    X

要么

keyA keyB data
A    1    X
A    3    X
A    5    X
A    7    X
B    1    X
B    3    X
B    5    X
B    7    X

我是否需要告知聚簇索引哪些鍵列具有較少的可能值,以允許它首先按該值對數據進行排序? 或者在首先訂購的性能方面無關緊要?

您應該首先使用最具選擇性的列來命令復合聚簇索引。 這意味着具有最大值的列與總行數相比較。

“B * TREE索引提高了從表中選擇一小部分行的查詢的性能。” http://www.akadia.com/services/ora_index_selectivity.html

本文適用於Oracle,但仍然相關。

此外,如果您有一個不斷運行並返回少量字段的查詢,您可以考慮創建一個包含所有字段的復合索引 - 它不必訪問基表,而是從索引中提取數據。

ligget78關於確保提及復合索引中第一列的評論非常重要。

如果使用(keyA,keyB)創建索引(無論是否為聚簇),那么這就是值的排序方式,例如第一個keyA,然后是keyB(這是你問題中的第二個案例)。 如果你想要反過來,你需要指定(keyB,keyA)。

它可能在性能方面很重要,當然取決於您的查詢。 例如,如果您有(keyA,keyB)索引並且查詢看起來像WHERE keyB = ...(不提及keyA)則無法使用索引。

正如其他人所說,排序基於您在索引創建腳本(或PK約束)中指定它的方式。 關於聚簇索引的一件事是,要記住很多事情。

通過在PK以外的其他內容上使用聚簇索引,可以獲得更好的整體性能。 例如,如果您正在編寫財務系統,並且報表幾乎總是基於活動的日期和時間(過去一年的所有活動等),那么該日期列上的聚簇索引可能會更好。 正如HLGEM所說,排序也可能受到聚集索引選擇的影響。

聚簇索引也可以比其他索引更多地影響插入。 如果您有大量的插入並且您的聚簇索引類似於IDENTITY列,則磁盤的特定部分可能存在爭用問題,因為所有新行都插入到同一位置。

對於小型查找表,我總是將聚簇索引放在PK上。 對於影響較大的表,盡管在選擇最佳表之前花些時間考慮(和測試)各種可能的聚簇索引是個好主意。

我相信SQL Server會按照你說的方式對它進行排序。 它假定您最了解如何訪問索引。

在任何情況下,我都會說,在可能的情況下,盡可能指定您想要的內容,而不是希望數據庫能夠解決這個問題。

您也可以嘗試兩種方式,運行一堆代表性查詢,然后比較生成的執行計划,以確定哪種方法最適合您。

請記住,聚簇索引是表存儲在磁盤上的物理順序。

因此,如果將聚簇索引定義為ColA,則在按照與聚簇索引相同的順序進行排序時,ColB查詢將更快。 如果SQL必須命令B,A它將需要執行后執行排序以實現正確的順序。

我的建議是在B,A上添加第二個非聚集索引。 此外,根據您的數據列的大小INCLUDE(讀取包含列),它可以防止需要鍵查找。 當然,如果此表沒有大量插入,因為您始終必須平衡查詢速度與寫入速度。

實際上,您的聚簇索引應該表示最有可能訪問數據的順序,以及保持insert \\ update IO cost的微妙平衡。 如果您的聚集索引是不斷插入頁面中間的,那么您可能會遇到性能損失。

像其他人所說,不知道表長,列大小等,沒有正確的答案。 大劑量測試的試驗和錯誤是您最好的選擇。

為了防止這種情況不明顯: 索引的排序順序對查詢中結果的排序順序沒有多大幫助。

在您的查詢中,您仍然必須添加

ORDER BY KeyA, KeyB

要么

ORDER BY KeyB, KeyA

優化器可能很樂意根據需要找到已在索引中物理排序的數據並節省一些時間,但是應該以特定順序傳遞數據的每個查詢都必須在其末尾具有ORDER BY子句。 如果沒有順序,SQL Server不會對記錄集的順序做出任何承諾,甚至不會從查詢到查詢以相同的順序返回。

是的,您應該建議,通常查詢引擎嘗試找出最佳執行計划和要使用的索引,但有時最好強制查詢引擎使用特定索引。 在規划索引時以及在查詢中使用索引時還有一些其他考慮因素。 例如,索引中的列排序,where子句中的列排序。 你可以參考以下鏈接了解:

http://ashishkhandelwal.arkutil.com/sql-server/quick-and-short-database-indexes/

  • 使用索引的最佳實踐
  • 如何獲得最佳性能表單索引
  • 聚集索引注意事項
  • 非聚集索引注意事項

我相信在規划索引時這會對你有所幫助。

您可以做的最好的事情是嘗試兩種解決方案並測量執行時間。

根據我的經驗,索引調整完全是科學的。

也許在索引列順序中使用keyA之前的keyB會更好

您可以按照通常希望它們在報表和查詢中排序的順序指定列。

我會擔心創建一個多列聚簇索引。 根據它的寬度,您可能會對您創建的任何其他索引的大小產生巨大影響,因為所有非聚簇索引都包含聚簇索引值。 如果值經常更改,則必須重新排序行,並且我的經驗是非代理鍵往往更頻繁地更改。 因此,如果您有可能更改的值,則將此作為群集的非聚簇索引創建可能會花費更多時間來處理服務器資源。 我不是說你不應該這樣做,因為我不知道你的列實際包含什么類型的數據(雖然我懷疑它們比A1,a2等更復雜); 我說你需要考慮這樣做的后果。 在承諾執行此操作之前,徹底閱讀有關群集副非聚簇索引的BOL可能是個好主意。

暫無
暫無

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

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