2013-02-06 279 views
0

我得到了一個超過12列的表。這是用於以檢索最新的7條爲HAVING子句中的列建立索引 - MySQL

SELECT * FROM data WHERE user_id IN(12,10,7,1) HAVING continent IN('Europe','America','Australia') AND NOT MATCH(weather) AGAINST('+"[blues]"' IN BOOLEAN MODE) || continent = 'Asia' AND MATCH(weather) AGAINST('+"[purples]"' IN BOOLEAN MODE) ORDER BY tb_id DESC LIMIT 7

總行數超過5 millionuser_idtb_id作爲PRIMARY KEY索引列的MySQL查詢。當我在SELECT前使用EXPLAIN時。 MySQL告訴它將從總共500萬條中讀取超過40萬條記錄。

所以,我應該索引大陸列或它不會幫助在這種情況下?

這裏是EXPLAIN結果

id = 1; select_type = SIMPLE; table = data; possible_keys = user_id; key = user_id; ref = NULL; rows = 582; Extra = Using where, Using filesort

+0

這是爲什麼在HAVING子句中? – Strawberry

+0

「HAVING」子句是後來刪除的「GROUP BY」子句的剩餘部分嗎? 「||」意圖是一個布爾OR還是字符串連接? 「大陸」是否已編入索引?你忘了發佈解釋計劃。 –

+0

大陸沒有編入索引。那就是我想知道的。而HAVING是GROUP BY – sanchitkhanna26

回答

1

首先,您的查詢可能是錯誤的。當你使用OR混合AND在哪裏或有子句或任何地方,你應該使用parantheses。其次,在你的情況下使用HAVING沒有任何意義,優化器很可能將它轉換爲WHERE子句。

兩者的區別在於,在確定要選擇哪些行時應用WHEREHAVING應用於結果集。因此,如果優化器不能很好地完成工作,您首先會獲得(幾乎)所有行,然後對其進行過濾。當你把這一切放在WHERE條款中時,你只會得到相關的行。 HAVING(幾乎)只有在使用GROUP BY時纔有意義。

所以,你最好把你的查詢是這樣的:

SELECT * FROM data 
WHERE user_id IN(12,10,7,1) AND 
(
(
continent IN('Europe','America','Australia') 
AND NOT MATCH(weather) AGAINST('+"[blues]"' IN BOOLEAN MODE) 
) 
OR 
(
continent = 'Asia' 
AND MATCH(weather) AGAINST('+"[purples]"' IN BOOLEAN MODE) 
) 
) 
ORDER BY tb_id DESC LIMIT 7 

要回答你的問題有關的指標,後期的解釋和創建表data的語句的結果。

+0

的擴展,感謝@tomboom。這裏是解釋 'ID = 1個 SELECT_TYPE的結果= SIMPLE 表=數據 possible_keys = USER_ID 鍵= USER_ID REF = NULL 行= 582 額外=使用,其中,使用filesort' – sanchitkhanna26

+0

請編輯您的問題並在那裏添加該信息。 – fancyPants

+0

爲了更好的可讀性,您可以用'\ G'而不是';'結束語句。然後列變成行,並且更容易發佈。 – fancyPants