【问题标题】:Do I need to set up a column with just a few possible values as an index for tSQL?我是否需要设置一个只有几个可能值的列作为 tSQL 的索引?
【发布时间】:2012-09-06 08:50:54
【问题描述】:

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

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

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

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

【问题讨论】:

  • 为什么BIT 不用于0,1 列?以后可能会扩展到更多值吗?
  • 好点。谢谢。我会改变它。不过,索引呢?

标签: sql sql-server tsql select indexing


【解决方案1】:

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

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

另一种选择是使用filtered indexcreate index .. on (name) where (deleted=0),但这不包括您deleted=1 感兴趣的情况。

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

请注意,如果您将低选择性键添加为索引中最左侧的键,并且您在谓词中指定此列(例如,WHERE name='...' 不添加任何条件deleted) 则不能使用索引,只能使用索引on (name)(或on (name, ...)),即。其中name 是最左边的键。

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

【讨论】:

    【解决方案2】:

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

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

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

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

    选择性 = 不同的值/行)

    2 / 1.000.000 = 0,000002 
    

    在另一种情况下:

    3 / 1.000.000 = 0,000003
    

    这些值非常低!

    或者换一种方式:

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

    第一种情况是 50%,第二种情况是 33%。

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

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

    【讨论】:

    • 只是出于好奇,列上的选择性应该是什么才能成为索引?
    • 您可以有一个估计的选择性比率,例如:((TotalRows / Distinc Values) / TotalRows) * 100. = 1 / Distinc values * 100。在第一种情况下,它是 (1.000.000 / 2 ) / 1.000.000 * 100 = 50%。 Sql Server 的优化器不使用该比率 > 15% 的索引
    猜你喜欢
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2021-09-12
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    • 2011-04-22
    • 1970-01-01
    相关资源
    最近更新 更多