動態謂詞的索引策略
假設 SQL Server 2012 標準版。
我的數據庫有一個包含 5 億行的表。該表有大約十幾個列,沒有一個很寬(一些 varchar(100) 和一些 int)。
聚集索引(也是主鍵)是一個標識列。
使用此表的應用程序有一個螢幕,使用者可以在其中搜尋大部分列。螢幕上的一個搜尋欄位是必需的,具有搜尋開頭或包含的選項,結果是
WHERE ABC LIKE 'something%' -- starts with
要麼
WHERE ABC LIKE '%something%' -- contains
與我的範例不同,實際查詢是參數化的。
其他搜尋欄位與上面的第一個範例一樣以搜尋開頭,但它們不是必需的。因此,可以搜尋這些欄位的任何組合,從而生成動態 where 子句。
鑑於此資訊,應創建哪些索引以獲得最佳性能?
請記住,我是查詢性能調整的新手,僅針對這種情況,我的天真的策略是為每一列創建一個非聚集索引,並對具有包含搜尋選項的列使用全文搜尋。我很想听聽為什麼或為什麼不是一個壞主意,以及更好的方法是什麼。
更新
我知道全文搜尋是如何優化“包含”搜尋的情況。
我對問題的另一個方面更感興趣:如何優化任何給定查詢謂詞中可能存在或不存在的其他搜尋欄位。可以從全文索引中受益的欄位的詳細資訊包含在我的問題中,只是為了幫助更全面地了解我的特定情況。
如果我是你,我會針對該表上的命中執行跟踪。它不應該過於密集,因為您將其限制為僅從您的應用程序對該表進行查詢。只執行 DTA (Database Tuning Advisor) 所需的最低要求。在這裡執行一天,在那裡執行一天,確保你得到一些週末的日子和一些月底的日子。然後通過 DTA 執行整個批次。
這就是為什麼,我敢打賭你有特定的列組合,這些組合會經常出現。您可以根據該資訊創建更複雜的索引。您可能還會發現您可以創建一些相關的統計資訊。基本上具有多於一列的統計資訊。例如,一起創建有關 City 和 State 的統計資訊可能會改進對這兩個列的查詢。
但是請確保您不要創建很多索引。在一張那麼大的桌子上,我猜你做了相當多的寫入,並且添加的每個額外索引都會減慢它們的速度。當然,您可以在批處理過程中完成大部分寫入操作。
還要確保您設置了一個自動過程來定期更新您的統計資訊。有了這麼多行,統計資訊不會經常自行更新。只有一次 500+20% 的行發生了變化,在 500 百萬行中,這是很多的。
根據提供的資訊很難說,但是…
你說的是閱讀。您不是在談論插入或更新。在我看來,“大約十幾個”非聚集索引可能會減慢寫入速度。再說一次,您的應用程序可能沒有很多插入或更新,這可能沒問題。還有將所有這些索引載入到記憶體中的問題。
我的建議是在開發/測試環境中測試各種策略,看看哪種策略最有效。
該影片可能會有所幫助: http ://www.brentozar.com/archive/2013/06/the-top-3-indexing-mistakes-in-sql-server-video/