2014-01-25 116 views
0

我想知道在以下情況下定義兩種索引類型的危害是什麼。組合多列索引以及多個單列索引

Tasks

TaskID (Primary, Auto Number) 
    OwnerID (Single Column Index) 
    AssignedToID (Single Column Index) 
    DateUpdated (Single Column Index) 
    TaskStatus (Single Column Index) 

    Mutli Column Index (AssignedToID, DateUpdated) 

有以下主要查詢...查詢DateUpdated是可選的。

  • 管理員可以篩選日期任務
  • 單列索引DateUpdated訪問

    WHERE 
        DateUpdated <= startDate 
        AND DateUpdated <= endDate 
    ORDER BY 
        DateUpdated DESC 
    
  • 單列索引DateUpdated訪問

    WHERE 
        TaskStatus = 'Active' 
    ORDER BY 
        DateUpdated DESC 
    
  • 用戶只能篩選分配的任務給他們

  • 多列索引訪問

    WHERE 
        DateUpdated <= startDate 
        AND DateUpdated <= endDate 
        AND AssignedToID = userID 
    ORDER BY 
        DateUpdated DESC 
    
  • 多列索引訪問

    WHERE 
        AssignedToID = userID 
        AND TaskStatus = 'Active' 
    ORDER BY 
        DateUpdated DESC 
    
  • DateUpdated

  • 單列索引TaskID被訪問的任何標準沒有提及

    WHERE 
        AssignedToID = userID 
        AND TaskStatus = 'Active' 
    ORDER BY 
        TaskID DESC 
    

看起來我可以通過在某些頻繁查詢中定義多列索引來提高性能,我有以下問題。

  1. 定義組合指數和多指數都有什麼壞處嗎?
  2. 如果查詢包含每列的謂詞而不管查詢中列的順序,SQL是否會優先於單索引合併的組合索引?
  3. 如果您有任何示例說明兩個索引可能有害,我想知道爲什麼以及如何,因此我可以相應地設計我的索引。

我的數據庫操作有95%的讀取和5%的寫入,所以我不太擔心索引寫入性能問題,但是我的讀取性能是最重要的。

回答

1

定義組合索引和多重索引都有什麼壞處嗎?

我寧願把它的維護開銷利大於弊:
- INSERT/UPDATE/DELETE在該表上會有點慢,每一個新的索引。
- 索引需要一些磁盤空間。

如果查詢包含每列的謂詞而不管查詢中列的順序,SQL是否會優先於單索引合併的組合索引?

查詢中列的順序無關緊要。

索引中列的順序很重要。
所以:
上(AssignedToIDDateUpdated)指數可用於尋找,而不是在(AssignedToID)指數,但在(DateUpdatedAssignedToID)不能用於謀取而不是在指數
指數(AssignedToID) 。

查詢優化器將根據估計的成本(根據統計信息(表/索引中的多少行以及值的分佈情況))來選擇要使用的索引。
它可能決定根本不使用你的索引 - 如果行數很少,掃描整個表格便宜,或索引選擇不夠。

如果查詢包含上AssignedToIDDateUpdated謂詞 - 上(AssignedToIDDateUpdated)中的索引是更可能(AssignedToID),以用於通過查詢優化比指數。
但它取決於查詢的所有其他元素和數據庫中的實際數據。

如果您有任何示例說明這兩個索引可能有害,我想知道爲什麼以及如何,因此我可以相應地設計我的索引。

當數據庫或/和請求數量顯着增加時,開銷可能變得明顯。

More about "too many indexes"
General indexing guidelines


根據你的主要查詢它看起來像非聚集索引應該是:

  • DateUpdated
  • AssignedToIDDateUpdated

可能:

  • TaskStatus) - 然而,如果假設90%的任務是'Active',你只能查詢'Active' - 那麼它是沒有用的。

不需要:

  • AssignedToID) - 因爲(AssignedToIDDateUpdated)指數將是足夠的。

之後,您可以驗證測試數據庫上的假設,數據足夠接近生產。