是否有适用非聚集索引的一般选择性规则?
我们知道不要在位列( 50/50 )上创建索引。“50/50发行版的行,可能会给您带来很少的性能增益”服务器中的索引位字段
那么,在应用索引之前,查询在Server中应该有多大的选择性呢?Server指南中是否有一般规则?25%的平均选择性分布? 10%的选择性?
这篇文章指出了大约31%的指数应该有多大的选择性?
发布于 2018-06-06 14:23:13
只有当决定要索引的列时才考虑列的选择性时,才会忽略索引可以做什么,以及它们通常用于什么。
例如,您可能有一个标识或guid列,它具有难以置信的选择性--独特,甚至--但从未被使用过。既然如此,谁在乎呢?为什么查询不涉及索引列?
选择更少的索引,即使是BIT列,也可以成为索引的有用或有用的部分。在某些情况下,大型表上非常非选择性的列在需要排序或按其分组时可以从索引中获得相当大的好处。
请接受以下查询:
SELECT COUNT(*) AS records
FROM dbo.Users AS u
JOIN dbo.Posts AS p
ON u.Id = p.OwnerUserId;如果在OwnerUserId上没有一个有用的索引,这是我们使用Hash连接的计划--这会溢出--但这是次要的。

有了一个有用的指数-- 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;他们最终会被封锁:

在索引就位后,select立即结束,而不会被阻塞。Server有一种有效访问所需数据的方法。
如果您想知道(使用Kumar提供的方程),OwnerUserId列的选择性是0.0701539878296839478
上
不要仅仅根据列的选择性来盲目地索引列。设计有助于工作负载高效运行的索引。在搜索相等谓词时,使用更多的选择性列作为主导键列通常是个好主意,但在范围搜索时可能不太有用。
发布于 2018-06-06 11:33:08
您所指的是“临界点”,Server优化器决定使用表扫描,而不是索引查找和键查找。
需要注意的是,临界点显然只影响非聚集索引(因为在使用聚集索引时不需要进行键查找),而且当非聚集索引覆盖时(所有选定的列都在键列中或索引的包含列中),提示点也不起作用。
尽管如此,行数并不是总行数的30%。这不是一个固定的值。
行数在页面数的25%到33%之间,因此,除非每页有1行,否则行的百分比要小得多。
参见金伯利·特里普在临界点查询答案中的例子
现在,要回答您的问题,在使用索引之前,它应该有多大的选择性?
根据您的行大小和页数,它可能非常有选择性。如果您想确保您的索引被使用,您希望您的索引包括在内。
https://dba.stackexchange.com/questions/208852
复制相似问题