2012-07-02 35 views
1

我有這個疑問這需要27秒內執行:可以優化此MySQL連接查詢嗎?

SELECT ocal_files.*, count(DISTINCT ocal_favs.username) as favs 
FROM ocal_files 
    INNER JOIN ocal_favs on ocal_favs.clipart_id = ocal_files.id 
GROUP BY ocal_files.id 
ORDER BY favs DESC​ 

(而不是用戶名應該user_id說明,因爲我有一個用戶表)

ocal_files有37457行,ocal_favs有18263

編輯結果的解釋

mysql> EXPLAIN SELECT ocal_files.*, count(DISTINCT ocal_favs.username) as favs FROM ocal_files INNER JOIN ocal_favs on ocal_favs.clipart_i 
d = ocal_files.id GROUP BY ocal_files.id ORDER BY favs DESC;                    
+----+-------------+------------+--------+----------------+---------+---------+---------------------------------+-------+---------------------------------+ 
| id | select_type | table  | type | possible_keys | key  | key_len | ref        | rows | Extra       | 
+----+-------------+------------+--------+----------------+---------+---------+---------------------------------+-------+---------------------------------+ 
| 1 | SIMPLE  | ocal_favs | ALL | rlb_clipart_id | NULL | NULL | NULL        | 18622 | Using temporary; Using filesort| 
| 1 | SIMPLE  | ocal_files | eq_ref | PRIMARY  | PRIMARY | 4  | openclipart.ocal_favs.clipart_id |  1 | Using where     | 
+----+-------------+------------+--------+----------------+---------+---------+---------------------------------+-------+---------------------------------+ 
2 rows in set (0.00 sec) 

爲什麼它慢?可以優化嗎?如果是,那麼如何?

+3

您的表是否被索引? –

+1

什麼是執行計劃?有關表格中的索引是什麼? –

+3

你有沒有['ANALYZE'](http://dev.mysql.com/doc/refman/5.1/en/analyze-table.html)?你可以讓MySQL ['EXPLAIN'](http://dev.mysql.com/doc/refman/5.1/en/using-explain.html)查詢嗎? –

回答

2

嘗試在

ocal_favs (clipart_id, username) 

創建索引,並確保有上ocal_favs.username一個NOT NULL約束或添加ocal_favs.username IS NOT NULL作爲條件。

這應該允許從ocal_files和指標得到所有的信息。

+0

我從來沒有使用索引做之前,我需要調用此查詢:'CREATE INDEX ON favs_index ocal_favs(clipart_id,用戶名) '? – jcubic

+0

因爲我相信人們,我聽說索引會提高性能。 – jcubic

+0

索引當然可以提高性能,我認爲這個會幫助你,但不要相信任何你可以測試的東西:) –

1

SQL優化打交道時,一個好的方法是隻選擇字段,你需要的,不是所有的人都在你的情況。這幾乎總是會對性能產生巨大影響,尤其是當字段爲BLOB's時。 而且,正如其他用戶指出的那樣 - 索引也非常重要,但前提是您已正確創建索引。 使用LIMIT子句也是一個好主意,如果您不需要一次顯示您的結果(我懷疑這是這種情況,因爲我不相信您會顯示30000的結果+記錄到用戶瀏覽器)...