6

假设我有下表

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

推荐什么以获得最佳性能?

  • UserName为和UserEmail单独创建非聚集索引

或者

  • 只有一个包括两列

请分享你的想法,为什么一个比另一个更可取。

4

3 回答 3

16

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

所以如果你有一个单一的复合索引

(UserID, UserName, UserEmail)

那么这个索引可能会在以下场景中使用:

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

但是这个单一的复合索引将永远无法用于搜索

  • 只是- 它是索引中的第二列,因此永远不能使用UserName索引
  • 只是- 它是索引中的第三列,因此永远不能使用UserEmail索引

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

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

于 2012-12-26T10:12:14.340 回答
4

定义索引的最佳方式完全取决于您将如何使用该表。仅通过查看表定义来选择索引是不明智的。

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

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

于 2012-12-26T08:22:21.990 回答
2

请分享你的想法,为什么一个比另一个更可取。

这取决于你做什么。

看,索引仅用于“从左到右”。因此,用户 ID 上的索引;如果我选择仅按用户名过滤,用户名将毫无用处。

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

  • Uniuqe 索引,聚集在 UserID 中,作为主键。
  • 用户名的唯一索引,非聚集。
  • UserEMail 上的唯一索引,非集群。

原因完全不是为了性能,而是:

  • 您将需要第一个作为外键关系的主键。
  • 您需要另外两个来正确处理唯一约束 - 没有索引就无法做到这一点。

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

性能确实排在最后——出于性能原因,所有这些索引都可能包含所有附加字段(不是作为索引的一部分,而是作为包含的列。但实际上,除非您允许多个注册,否则没有其他明智的方法可以让这个表工作对于同一个用户。

于 2012-12-26T08:27:20.423 回答