【问题标题】:Performance in SQL Server when there is PK and UQ index on the same column同一列上存在 PK 和 UQ 索引时 SQL Server 中的性能
【发布时间】:2012-10-15 20:49:43
【问题描述】:

在 SQL Server 2005 中,我遇到了一个带有唯一 ID 列(上面有唯一索引)和主键聚集索引的表(所以这个列上有明确的 2 个索引)。这是在此表上插入/更新/删除的主要性能因素吗?

我正在尝试提高很久以前创建的数据库的性能,我想知道删除这些冗余的唯一索引是否会有所帮助。数据库是否在每次内容修改时检查/重建这两个索引?或者性能增益会不会太小而无法解决这个问题?

这是一个示例索引使用输出:

INDEX   UserSeeks    UserScans  UserLookups UserUpdates
--------------------------------------------------------
1_PK    45517046      42911     245353       0
1_UQ    45517046      42911     245353       0
1_Other 45517046      42911     245353       0   
--------------------------------------------------------
2_PK    21538111      5685      231030      1121
2_UQ    21538111      5685      231030      1121
3_other 21538111      5685      231030      1121

这是我用来获取该数据的查询:

SELECT OBJECT_NAME(I.OBJECT_ID) AS ObjectName,
   I.NAME AS IndexName,
   S.user_seeks AS UserSeeks,
   S.user_scans AS UserScans,
   S.user_lookups AS UserLookups,
   S.user_updates AS UserUpdates
FROM sys.indexes I 
JOIN sys.dm_db_index_usage_stats S
  ON (S.OBJECT_ID = I.OBJECT_ID)
WHERE(database_id = DB_ID())

固定连接条件:

SELECT OBJECT_NAME(I.OBJECT_ID) AS ObjectName,
   I.NAME AS IndexName,
   S.user_seeks AS UserSeeks,
   S.user_scans AS UserScans,
   S.user_lookups AS UserLookups,
   S.user_updates AS UserUpdates
FROM sys.indexes I 
JOIN sys.dm_db_index_usage_stats S
  ON (S.OBJECT_ID = I.OBJECT_ID)
  AND(S.index_id = I.index_id)
WHERE(database_id = DB_ID())

【问题讨论】:

    标签: sql-server indexing


    【解决方案1】:

    索引通常以更新/插入/删除性能换取更好的选择性能。这几乎总是一件好事。

    数据库是否检查/重建每个内容的这两个索引 修改?

    必须,否则索引会过期,并返回错误的结果。

    或者性能增益会不会太小而无法解决这个问题?

    这取决于桌子上的活动。

    唯一约束也有一个功能:它使列保持唯一。由于没有索引就不能拥有唯一约束,因此在您的情况下,删除它似乎不是一个选项。

    【讨论】:

      【解决方案2】:

      这可能不是多余的索引。

      拥有一个只包含IDs 的更窄的非聚集索引很可能是一种有意的策略,以使某些查询受益和/或使外键验证更有效。

      我在此处对(成功)resolve a deadlock problem OP 的回答中建议了这种方法。

      【讨论】:

      • 但是执行计划显示SELECT查询使用PK索引,外键也引用PK索引(不是UQ)。并且主键还通过定义保证该列是唯一的,如果它是集群的,那么逻辑读取也基于此。如果这是真的,那么我认为 UQ 指数是不必要的。
      • @Ziouas - 听起来像。你可以使用sys.dm_db_index_usage_stats 来了解它是否被任何东西使用过。 Example query here。不过,它的统计数据最多只能追溯到实例上次重新启动的时间。
      • 这个未使用的索引查询很好的提示,我明天在工作中运行它,如果这些 UQ 曾经使用过,我会给你反馈。谢谢!
      • @Ziouas - 你的加入条件应该是(S.OBJECT_ID = I.OBJECT_ID AND S.index_id = I.index_id)
      • 好吧,我的错误,非常愚蠢的错误... 修复查询显示 UQ 几乎从未使用过(除了一些不好的情况,当表在 id 列上没有任何 PK only UQ )。所以我相信这些 UQ 在这种情况下真的是多余的,谜团已经解决了 :)
      猜你喜欢
      • 2011-10-20
      • 2010-11-08
      • 2021-04-19
      • 2015-08-07
      • 1970-01-01
      • 2012-04-12
      • 2013-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多