2010-02-17 116 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'。確定它沒有用。一些工具喜歡生成這樣的索引。另外,爲所有可能的查詢創建密鑰並不是一個好主意。