Sql-Server

在這個例子中,過濾索引理論上應該執行得更快嗎?

  • February 18, 2022

我有一個 SuperheroMovies 表,其中包含所有超級英雄電影,並且有一個名為“UniverseName”的列,其值為“Marvel”、“DC”、“Capcom”、“Unknown”。它還有名為“MovieId”(主鍵)和“MovieTitle”的列。(SuperheroMovies 中還有其他列,我們可以稱之為 OtherField1…OtherField25。)

聚集索引位於主鍵 MovieId 上。表上還有一個用於 MovieTitle 列的非聚集索引 IX_MovieTitle。

這是對 SuperheroMovies 表執行最多的查詢:

DECLARE @MovieTitlePrefix VARCHAR(50) = 'F'; -- This can be any single character from A to Z

SELECT MovieId, MovieTitle, UniverseName, OtherField1, OtherField2, OtherField3, ROW_NUMBER() OVER (PARTITION BY UniverseName ORDER BY MovieTitle) AS SortId
FROM SuperheroMovies
WHERE MovieTitle LIKE @MovieTitlePrefix + '%'
   AND UniverseName <> 'Unknown'

如果在查詢中創建並使用非聚集索引 IX_MovieTitle_FilteredOnUniverseName ON SuperheroMovies (MovieTitle) WHERE UniverseName <> ‘Unknown’ 而不是 IX_MovieTitle,它應該執行得更快嗎?

我仍然需要使用 IX_MovieTitle_FilteredOnUniverseName 在查詢中使用 UniverseName <> ‘Unknown’ 上的過濾器來獲得相同的結果集,對吧?

它至少會快一點,並且使用更少的磁碟空間,具體取決於UniverseName = 'Unknown'.

原始索引將允許查詢尋找正確的電影標題起始字元,並將殘差謂詞應用於每一行以確保它不是來自'Unknown'宇宙。

過濾後的索引仍會尋找電影標題的起始字元。但它不必應用剩余謂詞(它已經知道這些行都不存在)。如果有很多行帶有UniverseName = 'Unknown'.

此外,您可能應該UniverseName在索引定義中包含,原因如下:過濾列是否始終位於鍵/包含中?


邊欄:字元串連接的變數可能會導致動態搜尋計劃,除非您在查詢中包含RECOMPILE提示。這對您的案例可能很重要,也可能無關緊要,但需要注意。

引用自:https://dba.stackexchange.com/questions/257598