2012-11-07 82 views
3

我追蹤匹配的網站上在下面的MySQL MyISAM表:優化MySQL的慢數查詢和集團通過

CREATE TABLE `track_hits` (
    `hit_id` int(10) unsigned NOT NULL auto_increment, 
    `referer` varchar(255) default NULL, 
    `referer_checksum` int(10) default NULL, 
    `domain_checksum` int(10) default NULL, 
    `referer_local` enum('Yes','No') default NULL, 
    `request` varchar(255) default NULL, 
    `request_checksum` int(10) default NULL, 
    `embed_id` int(10) unsigned default NULL, 
    `embed_user_id` int(10) unsigned default NULL, 
    `embed_campaign_id` int(10) unsigned default NULL, 
    `date` datetime default NULL, 
    `day_checksum` int(10) default NULL, 
    `visit_id` int(10) unsigned default NULL, 
    PRIMARY KEY (`hit_id`), 
    KEY `referer_checksum` (`referer_checksum`), 
    KEY `date` (`date`), 
    KEY `visit_id` (`visit_id`), 
    KEY `embed_user_id` (`embed_user_id`), 
    KEY `embed_campaign_id` (`embed_campaign_id`), 
    KEY `day_checksum` (`day_checksum`), 
    KEY `domain_checksum` (`domain_checksum`), 
    KEY `embed_id` (`embed_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

表中有超過500萬行。

我希望每個廣告系列(embed_campaign_id)每天在特定日期範圍內的總點擊次數&總共唯一身份號碼(基於不同的visit_id)。我是這樣做的這個查詢:

SELECT COUNT(DISTINCT h.`visit_id`) AS `visits`, COUNT(h.`hit_id`) AS `hits`, `date` 
FROM (`track_hits` h) 
WHERE `h`.`embed_campaign_id` = '31' 
AND `h`.`date` >= '2012-10-07 07:00:00' 
AND `h`.`date` <= '2012-11-07 07:59:59' 
GROUP BY `h`.`day_checksum` 

大約需要15-25秒運行。

day_checksum是日期的crc32編碼版本,即「2012-11-07」。我用代替GROUP BY,速度沒有增加。

EXPLAIN回報:

id select_type table type possible_keys   key     key_len  ref  rows  extra 
1 SIMPLE  h  ref  date,embed_campaign_id embed_campaign_id 5   const 1648683  Using where; Using filesort 

我想過用每天彙總表,但該網站是局部的和數據庫中的所有日期爲GMT。因此,10/07 @ 7PM EST到11/07 @ 7PM EST將需要返回不同於PST的10/07 @ 7PM到11/07 @ 7PM PST的計數。

有什麼辦法可以加快速度嗎?

回答

2

你有一個索引每列。我認爲你可以通過複合(多列)索引獲得更好的性能。

http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html

事情是這樣的:

KEY compositeIndex (embed_campaign_id, date, day_checksum, visit_id, hit_id) 
+0

+1非常好的問題。雖然,我會建議(embed_campaign_id,date)用於where子句。 –

0

只是一些亂撞:

  • 做一個anaylize table
  • 變更引擎InnoDB的
  • dategroup by,要麼離開它完全地與day_checksum更換或兩者改變爲date(date)
  • 刪除大括號from (track_hits h)
  • 請確保它不是h ardware,這是瓶頸

最後,每天15-25秒一次不是很長時間等待。