索引的选择性应该如何

4 performance index sql-server performance-tuning

是否有关于何时应用非聚集索引的一般选择性规则?

我们知道不要在位列 50/50 上创建索引。“具有 50/50 分布的行,它可能会给您带来很少的性能提升” SQL Server 中的索引位字段

那么在应用索引之前,SQL Server 中的查询应该有多大的选择性?SQL Server 指南中是否有一般规则?色谱柱中 25% 的平均选择性分布?10% 选择性?

这篇文章说明了大约 31%?索引的选择性应该如何?

Eri*_*ing 7

仅在决定索引哪些列时才考虑列选择性会忽略很多索引可以做什么以及它们通常有什么用处。

例如,您可能有一个非常有选择性的标识或 guid 列——甚至是独一无二的——但从未被使用过。在这种情况下,谁在乎?为什么查询不涉及的索引列?

很少有选择性的索引,甚至是BIT列,都可以成为索引的有用或有用的部分。在某些情况下,大表上非常非选择性的列在需要排序或分组时可以从索引中受益很多。

加入

拿这个查询:

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

没有对 有用的索引OwnerUserId,这是我们的散列连接计划 - 溢出 - 但这是次要的。

坚果

有了有用的索引CREATE INDEX ix_yourmom ON dbo.Posts (OwnerUserId);——我们的计划发生了变化。

坚果

聚合体

同样,分组操作可以从索引中受益。

SELECT   p.OwnerUserId, COUNT(*) AS records
FROM     dbo.Posts AS p
GROUP BY p.OwnerUserId;
Run Code Online (Sandbox Code Playgroud)

没有索引:

坚果

带索引:

坚果

排序

排序数据可能是索引可以提供帮助的查询中的另一个症结点。

没有索引:

坚果

使用我们的索引:

坚果

阻塞

索引还可以帮助避免阻塞堆积。

如果我们尝试运行此更新:

UPDATE p
SET p.Score += 100
FROM dbo.Posts AS p
WHERE p.OwnerUserId = 22656;
Run Code Online (Sandbox Code Playgroud)

并同时运行这个选择:

SELECT *
FROM   dbo.Posts AS p
WHERE  p.OwnerUserId = 8;
Run Code Online (Sandbox Code Playgroud)

他们最终会阻塞:

坚果

有了我们的索引,选择立即完成而不会被阻止。SQL Server 有一种方法可以有效地访问所需的数据。

如果您想知道(使用 Kumar 提供的等式) OwnerUserId 列的选择性是 0.0701539878296839478

包起来

不要只是根据列的选择性盲目地索引列。设计可帮助您的工作负载高效运行的索引。在搜索相等谓词时,使用更具选择性的列作为前导键列通常是一个好主意,但在搜索范围时可能不太有用。