2014-10-02 192 views
0

我有一個簡單的查詢,需要2.5秒來評估。我想優化它,但我不知道如何做到這一點。任何人都可以建議如何優化? 邏輯是下一個:計算指定廣告系列的引薦來源分組的所有點擊次數。 有「解釋」下面的mysql查詢。表格點擊和用戶有很多行。簡單的mysql查詢優化大表

mysql> explain select count(*) as amount,ac.referrer from clicks ac 
    ->   inner join users a on a.id = ac.user_id 
    ->   where a.campaign_id = 26 group by ac.referrer 
    ->   order by amount desc; 

+----+-------------+-------+--------+-------------------+---------+---------+------------------------+---------+---------------------------------+ 
| id | select_type | table | type | possible_keys  | key  | key_len | ref     | rows | Extra       | 
+----+-------------+-------+--------+-------------------+---------+---------+------------------------+---------+---------------------------------+ 
| 1 | SIMPLE  | ac | ALL | ac_adv   | NULL | NULL | NULL     | 1607031 | Using temporary; Using filesort | 
| 1 | SIMPLE  | a  | eq_ref | PRIMARY,advoc_cam | PRIMARY | 4  | mydb.ac.user_id  |  1 | Using where      | 
+----+-------------+-------+--------+-------------------+---------+---------+------------------------+---------+---------------------------------+ 
2 rows in set (0.00 sec) 

編輯

對不起,未提供shemas,但現在沒有這個必要。現在我已經完全覆蓋了索引列的建議在接受的答案。

這是正確的解決方案添加索引(c.user_id,c.referrer)。其他指標已經存在並且沒有意義。但現在查詢完成時間爲0.2秒,而不是2.5-3秒。謝謝!

+1

請向我們展示表格定義! – undone 2014-10-02 09:04:56

+0

請給我們表結構。 試試這個:ALTER TABLE'clicks'ADD INDEX'referrer'('referrer'); – faster2b 2014-10-02 09:32:15

+0

我真的不明白。據推測,你已經有一個複合主鍵(引用者,user_id),並且users.id必須已經是一個PK。所以唯一剩下的就是給campaign_id添加一個索引 - 但我懷疑這會產生多大的影響。 :-( – Strawberry 2014-10-02 09:54:44

回答

0

嗯,我可能會重寫查詢爲:

SELECT c.referrer, 
     count(*) amount, 
    FROM clicks c 
    JOIN users u 
     ON u.campaign_id = 26 
    AND u.id = c.user_id 
GROUP BY c.referrer 
ORDER BY amount DESC 

只是爲了能夠清楚是怎麼回事。

您的基本查詢大概和它一樣好,所以您需要索引來提高性能。

對於JOIN給用戶,u.id上的主鍵應該不錯,但是您可能會從(u.campaign_id, u.id)上的組合獲得更好的性能。

對於主表的點擊,您應該試試c.user_idc.referrer上的索引,也可能是兩個可能的複合物(c.user_id, c.referrer)(c.referrer, c.user_id)。使用EXPLAIN計劃來確定哪些是possible_keys,並刪除那些沒有幫助的。

如果查詢不使用它們,但它們顯示在possible_keys中(您只能爲每個表使用一個或連接 - 計劃的一行),您可能不得不暗示某些索引。

對於每個表上的組合,其中兩個索引覆蓋全部四個參考列,例如, (u.campaign_id, u.id)(c.user_id, c.referrer)查詢應該由索引覆蓋,而不需要訪問應該進一步提高性能的錶行。另外請記住,任何新的索引都會減慢DML操作(INSERT,UPDATE,DELETE)的位置,因爲它們包含由索引引用的列,因此如果您的寫入速率很高,最好對此命中改爲查詢。

-1
mysql> explain select count(*) as amount,ac.referrer from clicks ac 
->   inner join users a on a.id = ac.user_id AND a.campaign_id = 26 
->   group by ac.referrer 
->   order by amount desc; 

在您的查詢中更改WH和。可能是它會更快

+0

這將會有沒有影響,優化器會爲你排序。 – Arth 2014-10-02 09:43:14

0

嘗試

有場(CAMPAIGN_ID, user_id)

在用戶表中的鍵 - >這將遍歷用戶表,然後添加點擊每個用戶找到。