Index

具有 WHERE 和 GROUP BY 的複合索引

  • June 13, 2022

對於此查詢:

SELECT * FROM dogs WHERE a = ? AND b = ? GROUP BY c

哪個是更好的綜合指數:

INDEX(a, b, c)

或者

INDEX(c, a, b)

您通常需要第一個索引

INDEX(a, b, c)

或類似的

INDEX(b, a, c)

這是因為然後可以查找aandb列(僅讀取確切的必要行),並且結果仍將按 排序c,這意味著GROUP BY不需要支持排序。


而另一個選項

INDEX(c, a, b)

表示雖然數據可能按 排序c,但需要讀取所有行並驗證它們是否符合aandb條件。


如果您的 RDBMS 支持,您可能還想添加INCLUDE列,以支持其餘SELECT列。

好吧,如果沒有關於數據和數據分佈的更多細節,很難說。除了Charlieface的出色回答和Brendan McCaffrey的評論之外,我想說這取決於數據選擇性。

如果 a 或 b 中的任何一列將您的結果集縮小到小於 1%,而另一列將其過濾得更遠,那麼第一列後跟第二列就可以了——即使相反的順序也無關緊要,只要它是相等運算符。

當不等式運算符發揮作用時,故事變得不同

讓我們以 StackoverFlow 數據庫為例:

select * from Users where Reputation = 1  and  Location = 'Switzerland' 

在這裡,我將首先使用以下命令檢查選擇性:

select * from Users where Reputation = 1 -- 6044557 rows
select * from Users where Location = 'Switzerland' -- 4723 rows

因此,如果我們僅在 Location 列上創建索引,這本身就很好,並且邏輯讀取將從 142,000 下降到 14498:

在此處輸入圖像描述

如果我們修改這個索引並在索引中添加 Reputation 會怎樣:

在此處輸入圖像描述

邏輯讀取降至 5447。即使您更改索引中列的順序,邏輯讀取仍保持不變。

讓我只介紹一個不等式運算符的範例。

索引定義為:CREATE INDEX Combined ON Users(Location, Reputation)

邏輯讀取位於 9065

在此處輸入圖像描述

如果我們改變索引中列的順序並重新定義為:CREATE INDEX 組合 ON Users(Reputation, Location)

邏輯讀取將更改為 17839:

在此處輸入圖像描述

因此,只要它是相等運算符並且所有這些條件都以漸進方式過濾行並不重要 - 這意味著在第一個條件下,行數從 100 萬減少到 1000,在第二個條件下,行數進一步減少到 500等等。

要使用 group by,您需要使用聚合函式。

希望這可以幫助。

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