SQL Server为一列创建多个非聚簇索引,而在一个索引中只有多列

时间:2012-12-26 07:55:06

标签: sql-server multiple-columns non-clustered-index

假设我有以下表格

  • UserID(身份)PK
  • UserName - 唯一非空
  • UserEmail - 唯一非空

建议什么才能获得最佳性能?

  • 分别为UserNameUserEmail创建非聚集索引

OR

  • 只包括两个列

请分享你为什么一个人优于其他人的想法。

3 个答案:

答案 0 :(得分:13)

另一个需要考虑的重点是:只有在引用了n个最左边的列时才会使用复合索引(由多个列组成)(例如,在WHERE子句中)。

因此,如果您在

上有一个复合索引
(UserID, UserName, UserEmail)

然后可以在以下场景中使用 索引

  • 当您单独搜索UserID时(仅使用最左边的1列 - UserID
  • 当您搜索UserIDUserName时(使用最左侧的2列)
  • 当您搜索所有三列时

但是这个单一的复合索引从不能够用于

上的搜索
  • 只是UserName - 它是索引中的第二列,因此
  • 无法
  • 只是UserEmail - 它是索引中的第三列,因此无法

请记住这一点 - 仅仅因为列是索引中的一部分并不一定意味着仅支持单个列上的搜索并加速该索引!

因此,如果您的使用模式和应用程序确实需要单独搜索UserName和/或UserEmail(不提供其他搜索值),那么您必须单独创建这些列上的指数 - 只有一个单一的化合物根本没有任何好处。

答案 1 :(得分:4)

定义索引的最佳方式完全取决于您将如何使用该表。通过查看表定义,没有合理的方法来选择索引。

如果您的代码使用用户名搜索您的表,或者通过用户名将表与另一个表连接起来,那么在该列上定义索引是明智的。如果您的代码使用两列(用户名和用户邮件)将表与另一个表连接起来,那么为这两列定义索引是明智的。由于您的所有列都被定义为唯一的,因此我几乎不相信这种情况,因此您不需要在该表上使用多个列索引。

关于使用多个列索引可能还有一些额外的建议:多个列索引也用于部分符合索引但具有条件的过滤器。
例: 如果您在用户名和用户邮件上定义了一个两列索引(按给定顺序),那么您将在搜索中获得性能提升,这些搜索会过滤两列(用户名和用户邮件)。使用该索引,您还可以在仅使用用户名的过滤器中获得性能提升,因为这是索引的第一列,但不是通过usermail搜索,这是因为索引的第二列不能单独使用。
规则是:索引可用于使用精确匹配列进行过滤,或使用与索引定义中后续顶部列匹配的列子集进行过滤。

答案 2 :(得分:2)

  

请分享你为什么一个人优于其他人的想法。

这取决于你做了什么。

请参阅,索引仅用于“从左到右”。所以,UserID上有一个indes;如果我选择仅按UserName过滤,则UserName无用。

一般来说,我会在这里假设三个指数:

  • Uniuqe Index,以UserID集群,作为主键。
  • UserName上的唯一索引,非群集。
  • UserEMail上的唯一索引,非群集。

原因完全不是表演,而是:

  • 您将需要第一个作为forein密钥关系的主键。
  • 你需要另外两个正确处理独特的约束 - 没有索引就没有办法做到这一点。

此外,您需要灵活地通过UserName和UserEMail进行搜索,这意味着无法仅将它们组合在一起。

性能真的进入最后 - 由于性能原因所有这些索引可能包含所有其他字段(不是作为索引的一部分,而是包含在列中。但实际上,没有其他明智的方法可以让这个表工作,除非你为同一个用户提供多个注册。