Sql-Server

索引應該有多大的選擇性

  • June 18, 2018

是否有關於何時應用非聚集索引的一般選擇性規則?

我們知道不要在位列 50/50 上創建索引。“具有 50/50 分佈的行,它可能會給你帶來很少的性能提升” SQL Server 中的索引位欄位

那麼,在應用索引之前,SQL Server 中的查詢應該有多大的選擇性呢?SQL Server 指南中是否有一般規則?色譜柱中的平均選擇性分佈為 25%?10% 選擇性?

這篇文章說大約 31%?索引應該有多大的選擇性?

僅在決定要索引哪些列時才考慮列選擇性會忽略很多索引可以做什麼以及它們通常有什麼用處。

例如,您可能有一個身份或 guid 列,它具有令人難以置信的選擇性——甚至是唯一的——但從未被使用過。在那種情況下,誰在乎呢?為什麼查詢不涉及的索引列?

選擇性更少的索引,甚至是BIT列,都可以成為索引的有用或有用部分。在某些情況下,大型表上非常非選擇性的列在需要對其進行排序或分組時可以從索引中受益匪淺。

加入

接受這個查詢:

SELECT COUNT(*) AS records
FROM dbo.Users AS u
JOIN dbo.Posts AS p
ON u.Id = p.OwnerUserId;

如果沒有有用的索引OwnerUserId,這是我們使用 Hash Join 的計劃——它會溢出——但這是次要的。

堅果

有了一個有用的索引CREATE INDEX ix_yourmom ON dbo.Posts (OwnerUserId);——我們的計劃就會改變。

堅果

骨料

同樣,分組操作可以從索引中受益。

SELECT   p.OwnerUserId, COUNT(*) AS records
FROM     dbo.Posts AS p
GROUP BY p.OwnerUserId;

沒有索引:

堅果

有一個索引:

堅果

排序

對數據進行排序可能是索引可以提供幫助的查詢中的另一個癥結所在。

沒有索引:

堅果

使用我們的索引:

堅果

阻塞

索引還可以幫助避免阻塞堆積。

如果我們嘗試執行此更新:

UPDATE p
SET p.Score += 100
FROM dbo.Posts AS p
WHERE p.OwnerUserId = 22656;

並同時執行此選擇:

SELECT *
FROM   dbo.Posts AS p
WHERE  p.OwnerUserId = 8;

他們最終會阻止:

堅果

有了我們的索引,選擇立即完成而不會被阻塞。SQL Server 有一種方法可以有效地訪問它需要的數據。

如果您想知道(使用 Kumar 提供的公式) OwnerUserId 列的選擇性是0.0701539878296839478

包起來

不要只是盲目地根據它們的選擇性來索引列。設計可幫助您的工作負載高效執行的索引。當您搜尋相等謂詞時,使用更具選擇性的列作為前導鍵列通常是一個好主意,但在搜尋範圍時可能不太有用。

引用自:https://dba.stackexchange.com/questions/208852