【问题标题】:How do I address an issue with an overly wide index?如何解决索引过宽的问题?
【发布时间】:2014-10-07 03:58:11
【问题描述】:

我还不是很精通 SQL。我正在学习,但这是一个缓慢的过程。我正在从事一个项目,该项目将大量信息存储在 SQL Server 的数据库中。在其中一个表 ContactInformation 中,当尝试修改条目时遇到错误,因为非聚集索引由所有地址信息 exceeds 900 bytes 组成。我使用sys.dm_db_index_usage_stats 来验证修改表中的条目会导致3 user_seeks 和1 user_update

C# 代码似乎没有直接调用索引。它执行一个DbCommand,其中包含一个Update 类型的存储过程命令和19 个参数。我的想法是要么消除索引,要么尝试将DbCommand 分解为具有较少参数的多个更新,以期使用较小的索引。

由于缺乏经验,我有点不知所措。我欢迎任何关于下一步转向的建议。

索引包括以下内容:

| Name                 | Data Type     | Size |
|----------------------|---------------|------|
| ContactInformationID | int           | 4    |
| CompanyID            | smallint      | 2    |
| Address1             | nvarchar(420) | 840  |
| Address2             | nvarchar(420) | 840  |
| City                 | nvarchar(420) | 840  |
| State                | nvarchar(220) | 440  |
| PostalCode           | nvarchar(120) | 240  |
| Country              | nvarchar(220) | 440  |

是的,大多数列都过大。我们显然是从另一个项目继承了这个数据库。我们的软件将大多数列限制为不超过 100 个字符,但也有一些异常值。

【问题讨论】:

  • 组成索引的列的SQL数据类型和长度是什么?
  • 你能更规范化表格吗?如果可以的话,您可以在外键(通常是ints)上建立索引,这会使索引变得更小。
  • SQL Server 将允许您使用索引提示来尝试强制它使用该索引...您是否走上了这条路?
  • @Twelfth 我不知道这些。一些关于它们的信息表明它们对于不熟悉的人来说是危险的。
  • 为什么所有这些信息都必须是索引键?应用程序是否真的在 Address1 和 Address2 等列上寻找(考虑到它们也可能为空)?如果不是(可能)使它们包含列。

标签: c# sql sql-server non-clustered-index


【解决方案1】:

索引大小限制仅适用于键列。它适用于所有基于 B-Tree 的存储模式(NCI 和 CI)。存在这个限制是为了确保树扇出一定程度,以限制树的高度。

如果您不需要在 Address1 和 Address2 等列上进行搜索(考虑到它们也可能为空),则将这些列包含在列中。

索引键不应长于产生唯一索引的最短键前缀。与包含的那一列相比,此后的每一列都没有帮助。

【讨论】:

    【解决方案2】:

    如果 ContactInformationID 是唯一的,我感觉它很可能是唯一的,那么在索引中包含任何其他字段都是没有意义的。

    这样的索引仅对 ContactInformationID 的值作为查询参数存在的查询有用,并且当它存在时,其余字段无关紧要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多