1

我正在创建一个可能包含数百万条记录的 SQL Server 2008 数据库,我想知道是否需要将以下内容定义为索引:

  1. 可能只包含 0 和 1 的 TINYINT 列?

  2. TINYINT 列可能仅包含:0、5 和 6?

PS。这两个列都将在 WHERE 子句中用于选择。

4

2 回答 2

5

不,基本上不会单独使用这些列上的索引。

但是这种低选择性键非常适合组合键,作为索引中最左边的列。例如,说TINYINT (0,1)(为什么不使用bitbtw?)是deleted列。您经常查询以 . 为谓词WHERE deleted=0 AND ...。将此添加为聚集索引中最左边的列通常是正确的方法。或者,如果谓词是,比如说,WHERE name = '...' AND deleted=0你应该做一个非聚集的index on (deleted, name)

另一种选择是使用过滤索引create index .. on (name) where (deleted=0)但这并不涵盖deleted=1.

对于具有很少不同值的列(例如type列)也是如此。同样,使其成为复合索引中最左边的键通常很有意义。

请注意,如果您在索引中添加一个低选择性键作为最左边的键,并且您没有在谓词中指定此列(例如,不WHERE name='...'添加任何条件deleted),则无法使用索引,只能使用索引on (name)(或on (name, ...)) 可以使用,即。name最左边的键在哪里。

为什么不把它设为最右边的键?例如。index on (name, deleted)? 因为通常没有任何好处,只有当您想强制执行唯一约束时。只有 0 或 1 可供选择,一个index on (name)或一个index on (name, deleted)基本上提供相同的性能(如果它们可以使用的话)。将低选择性键放在左侧可启用某些范围扫描方案(例如WHERE type=5)。

于 2012-09-06T08:57:46.173 回答
2

这不是一个好主意,因为索引的选择性会很低,并且因此而不是“加速”,这可能是一个缺点。

具有相同值的行越少,索引的选择性越好

在其他一些情况下,甚至全表扫描也可能更有效。

假设:您有 100 万行。那么第一个索引的选择性为:

选择性=不同的值/行)

2 / 1.000.000 = 0,000002 

在另一种情况下:

3 / 1.000.000 = 0,000003

这些值非常低!

或者以不同的方式:

估计选择性比 =(TotalRows / Distinct values)/ TotalRows * 100 = 1/Distinc 值 * 100。

在第一种情况下为 50%,在第二种情况下为 33%。

Sql server 的优化器不使用这个比率大于 15% 的索引。

(我的计算是一个简单的估计,但你可以在MSDN中找到统计信息)

于 2012-09-06T08:53:21.403 回答