2011-09-19 22 views
7

請參閱下面的查詢。我應該在表上創建哪個索引,以便查詢將使用索引並避免使用臨時文件和文件夾?我已經嘗試了許多不同的指數組合,並閱讀advice here,但我似乎無法弄清楚。我解釋說,要麼Using Where(無指標),或Using Where Using Temporary, Using FilesortMySQL索引爲分組/ By Order

下面是一個簡單的查詢。所有列都是整數。

SELECT c1, Sum(c2) 
FROM table 
WHERE c3 IS NOT NULL 
AND c4 = 2011 
AND c5 = 0 
AND c6 In (6,9,11) 
GROUP BY c1 
+1

請記住,MySQL只能爲每個表使用一個索引,所以如果您在列上放置索引來優化GROUP BY,您可能最終會傷害到自己,因爲WHERE子句未優化,最終有更多工作要完成(即全表掃描)。 –

+3

我明白,但是有什麼辦法可以創建一個可以被GROUP BY和WHERE子句使用的索引嗎? – bradvido

回答

7

這應該對你有所幫助。重寫查詢,如下所示:

SELECT c1, Sum(c2) 
FROM table 
WHERE c4 = 2011 
AND c5 = 0 
AND c6 In (6,9,11) 
AND c3 IS NOT NULL 
GROUP BY c1 

現在創建列複合指數(C4,C5,C6)按該順序列。索引中的列應以與WHERE子句中的列相同的順序顯示。否則,索引不起作用。這個索引的選擇性足夠窄,臨時表上的文件(對於分組)應該是快速的。

移動C3到查詢結束的原因如下。作爲一個例子,讓我們假設c3可以取0到100之間的值(或者它可以是NULL)。如果運行「IS NOT NULL」查詢,則Mysql需要遍歷幾乎所有的B-Tree索引,除了與NULL對應的邊緣。因此,MySQL決定全表掃描比遍歷索引中的所有不同路徑更容易。另一方面,如果你的查詢是一個「IS NULL」並且你的索引是(c3,c4,c5,c6),那麼Mysql將會使用這個索引。這是因爲在這種情況下,Mysql只需要遍歷對應於NULL值的索引樹的部分。

那種指標MySQL需要的是非常依賴於有問題的查詢。按照@louis的建議在所有列上創建索引不是一個好主意!

+0

感謝您的詳細解釋! 「 – bradvido

+5

」索引中的列應以與WHERE子句中的列相同的順序出現,否則索引將無法工作。「查詢優化器不關心如何訂購'WHERE'子句。 'SELECT ...FROM foo WHERE bar = 1 AND baz <5'與SELECT ... FROM foo WHERE baz <5 AND bar = 1'具有完全相同的執行計劃,並以完全相同的方式使用索引。條件類型(相等或不平等,有選擇性或不相關)是重要的,而不是在WHERE條款中出現的地方。 – Air

+0

我不確定這是否屬實。根據我的經驗,索引定義的順序很重要,但不是where子句的順序。 –

-1

通過經驗,我應該說:建立索引在 「where」 子句中的所有列(但在這裏,不C6)

至少,C4和C5。

的「分組依據」子句將查詢結果排序。如果結果中有很多記錄,它也可能對索引c1有用。

c3僅作爲「非空」進行測試。但索引它也可以改善事情,這是要測試的。

Hopz這是有幫助的。

0

我相信這個問題是與條款 'ORDER BY 2 DESC'。即使c2索引SUM(C2)不是。

至於哪些索引你「應該」有,依賴於數據,所以我真的不能評論。

+0

爲了參數的緣故,我們假設我沒有使用ORDER BY子句。 (我已經從問題中刪除了它)。我仍然無法找到工作的索引。 – bradvido