2010-02-17 115 views
2

我有一个包含多个非PK相关索引的表。不幸的是,有几个索引引用相同的排序顺序引用同一列。我通常创建覆盖索引,这些索引代表我的表中非PK相关索引的聚合,因为只要该列被索引,在查询期间将酌情使用它。我的问题很简单:会在相同的排序顺序浪费资源的几个索引中索引相同的列,或者SQL Server知道列已经被索引并且只是交叉引用以实现优化目的?SQL Server索引的优化

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

+0

只需注意:具有特定顺序的复合索引确实会提高围绕该顺序构建的查询的性能。通过使用索引扫描与索引查找之间的折衷,创建索引会简化一些事情,这些索引扫描速度要快得多。 ORDER BY将利用索引(如果存在)。 – 2010-02-17 23:37:43

回答

1

我不清楚你在问什么。

考虑列A,B,C,& D上的表上的索引D.您有(A,B)和(B,A)索引,所有按升序排序。在这种情况下,是的,这将构建两个索引,但是附加索引不会被浪费,因为索引中的所有前面的列都存在重复行时,索引中的附加列仅从搜索透视图中提供帮助。

另一方面,具有附加“覆盖列”C和具有附加“覆盖”列D 的另一个索引(A,B)的(A,B)的索引将会浪费空间。你应该只用(A,B)+ C,D。

2

它将占用两倍的空间,但更重要的是,它会减慢插入,同时更新所有索引。

+0

那么我的覆盖索引方法是一个更优化的场景吗? – 2010-02-17 22:13:17

1

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

4

每个索引都是分开的 - 没有交叉引用等等。所以是的,如果这些指标是重复的,你最终可能会浪费一些时间。但是:在多个索引中包含单个列是完全有意义的 - 像复合索引(几个字段)等事物可能是并排存在的。

SQL Server作为2005年有一个非常不错的功能叫做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 
1

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

我遇到了很多次索引表t(A,B,C),如'A','A,B','A,B,C'。确定它没有用。一些工具喜欢生成这样的索引。另外,为所有可能的查询创建密钥并不是一个好主意。