【问题标题】:Optimization of SQL Server IndexesSQL Server 索引的优化
【发布时间】:2011-01-18 02:14:22
【问题描述】:

我有一个包含几个非 PK 相关索引的表。不幸的是,存在一些重复性,因为多个索引以相同的排序顺序引用同一列。我通常会为我的表创建代表非 PK 相关索引聚合的覆盖索引,因为只要该列被索引,它就会在查询期间适当地使用它。我的问题很简单:是否以相同的排序顺序在多个索引中索引同一列会浪费资源,还是 SQL Server 知道某个列已被索引并且只是为了优化目的而交叉引用?

更新: 未来的一点是询问具有轻微变化的重复索引是否会改善 ORDER BY 活动。例如,如果我按 A、B DESC、D 排序,那么具有该顺序的特殊索引实际上会比包含具有相同排序顺序的这些列的单个覆盖索引提高性能。我的印象是 ORDER BY 只会依赖索引,并且出于性能原因不需要存在特殊索引。

【问题讨论】:

  • 请注意:具有特定顺序的复合索引确实会提高围绕该顺序构建的查询的性能。创建覆盖索引将通过使用索引扫描与索引搜索的权衡来简化事情......这要快得多。 ORDER BY 将利用索引(如果存在)。

标签: sql-server-2008 indexing


【解决方案1】:

要使用的索引数是性能选择与插入/更新/删除之间的选择。磁盘空间不太重要。

我多次遇到表 t(A, B, C) 的索引,例如 'A'、'A,B'、'A,B,C'。当然没用。一些工具喜欢生成这样的索引。此外,为所有可能的查询创建键也不是一个好主意。

【讨论】:

    【解决方案2】:

    我不清楚你在问什么。

    考虑具有 A、B、C 和 D 列的表上的索引。您在 (A,B) 和 (B,A) 上有一个索引,所有索引都按升序排序。在这种情况下,是的,这将构建两个索引,但不会浪费额外的索引,因为从搜索的角度来看,索引中的其他列仅在索引中所有前面的列都存在重复行时才有帮助。

    另一方面,(A,B) 上的索引带有额外的“覆盖列”C,另一个索引 (A,B) 带有额外的“覆盖”列 D会浪费空间。您应该只使用 (A,B) + C,D。

    【讨论】:

      【解决方案3】:

      每个索引都是独立的——没有交叉引用等等。所以是的,如果这些索引是重复的,你最终可能会浪费一些时间。但是:在多个索引中包含单个列是完全有意义的——诸如复合索引(几个字段)之类的东西可能并排存在。

      2005 年的 SQL Server 有一个非常好的功能,称为 DMV(动态管理视图),它允许您检查

      • 根本没有使用索引
      • 可能会加快查询加载速度的缺失索引

      查找缺失的索引:

      SELECT  
          object_name(object_id), d.*, s.*
      FROM
          sys.dm_db_missing_index_details d 
      INNER JOIN 
          sys.dm_db_missing_index_groups g ON d.index_handle = g.index_handle
      INNER JOIN 
          sys.dm_db_missing_index_group_stats s ON    g.index_group_handle = s.group_handle
      WHERE   
          database_id = db_id()
      ORDER BY  
          object_id
      

      查找未使用的索引:

      DECLARE  @dbid INT
      
      SELECT @dbid = DB_ID(DB_NAME())
      
      SELECT   
          OBJECTNAME = OBJECT_NAME(I.OBJECT_ID),
          INDEXNAME = I.NAME,
          I.INDEX_ID
      FROM     
          SYS.INDEXES I
      JOIN 
          SYS.OBJECTS O ON I.OBJECT_ID = O.OBJECT_ID
      WHERE    
          OBJECTPROPERTY(O.OBJECT_ID, 'IsUserTable') = 1
          AND I.INDEX_ID NOT IN (SELECT S.INDEX_ID
                                  FROM SYS.DM_DB_INDEX_USAGE_STATS S
                                  WHERE S.OBJECT_ID = I.OBJECT_ID
                                          AND I.INDEX_ID = S.INDEX_ID
                                          AND DATABASE_ID = @dbid)
      ORDER BY 
          OBJECTNAME, I.INDEX_ID, INDEXNAME ASC
      

      【讨论】:

        【解决方案4】:

        每次将列包含在索引中时,都会使用空间 - 即使您有其他类似的索引。

        【讨论】:

          【解决方案5】:

          它会使用两次空间,但更重要的是它会在更新所有索引时减慢插入速度。

          【讨论】:

          • 那么我的覆盖索引方法是不是更理想的方案?
          猜你喜欢
          • 1970-01-01
          • 2014-01-09
          • 2016-10-12
          • 2019-05-26
          • 1970-01-01
          • 1970-01-01
          • 2023-03-04
          • 1970-01-01
          • 2012-08-05
          相关资源
          最近更新 更多