2011-09-21 32 views
2

我有一個相當大的表(> 10.000行),它將快速增長得更快。在這個表我運行下面的查詢:MySQL:GROUP BY上的索引

SELECT *, MAX(a) FROM table GROUP BY b, c, d 

目前EXPLAIN告訴我,有沒有按鍵,沒有任何可能的密鑰和它的「使用臨時;使用文件排序」。這樣的桌子最好的關鍵是什麼?

回答

1

在什麼工作結束時對所述查詢的修改如下:

SELECT b, c, d, e, f, MAX(a) FROM table GROUP BY b, c, d 

和創建一個索引(B,C,d,E,F)。

非常感謝您的幫助:這裏的提示非常有用。

4

那麼複合鑰匙b+c+d+a呢?

順便說一句,SELECT *是沒有意義的情況下,當你有GROUP BY

+0

我爲我的無知道歉,但你能解開你的陳述「Btw,SELECT *沒有意義,當你有GROUP BY」時? –

+1

@Adrien Hingert:'SELECT'中的每一列都應該用在GROUP BY中,或者用於聚合函數(COUNT,SUM等等)。否則,「不可能」說出要選擇的值。所有「成熟」的數據庫,例如SQL Server,Oracle或Postgres都遵循這個ANSI SQL要求,但是mysql並沒有(它有一個特殊的模式來打開它) – zerkms

2

主索引現場B,C,d是,如果適用不錯。
在這種情況下,你只是做一個

SELECT * FROM table1 
group by <insert PRIMARY KEY here> 

如果不把一個指數B,C,d。
也許在一個,取決於性能。

如果b,c,d始終一致使用,則對所有三個使用複合索引。

非常重要!總是聲明一個主鍵。如果沒有它,InnoDB的性能將會下降。

要詳細說明@zerkms,只需將這些列放入group by子句中,該子句將完全定義您所選擇的行。
如果您select *可能是好的,但不是最大(a)是不需要的,也不是羣組。
另請注意,max(a)可能來自與其餘字段不同的行。

是有一定道理的唯一的使用情況是:

select t1.*, count(*) as occurrence from t1 
inner join t2 on (t1.id = t2.manytoone_id) 
group by t1.id 

哪裏t1.id是PK。

我認爲你需要重新考慮這個問題。
提出一個新問題,解釋你想要的真實代碼。
並確保詢問how to make the outcome確定, so that all values shown are functionally dependent on the group by clause

+0

「b + c + d'索引的任何原因是主? – zerkms

+0

「非常重要!總是聲明一個主鍵。如果沒有它,InnoDB的性能會很糟糕。「---是的,這是顯而易見的,但是**爲什麼你堅持用PK進行分組**?通過PK和常規非空密鑰進行分組有什麼區別? – zerkms

+0

」如果你選擇*這可能是好的,但不是最大的(a)是不需要的。「---這是不正確的。它完全沒有意義的分組 – zerkms