mysql - 优化慢速 SQL 计数查询和按天分组

标签 mysql count query-optimization

我在以下 MySQL MyISAM 表中跟踪网站的点击量:

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 替换为 DATE(h.date),但速度没有提高。

解释返回:

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

我曾考虑过每天使用汇总表,但该站点已本地化并且数据库中的所有日期均采用格林威治标准时间。所以 10/07 @ 7PM EST 到 11/07 @7PM EST 将需要返回与 10/07 @ 7PM PST 到 11/07 @7PM PST 不同的计数。

有什么办法可以加快速度吗?

最佳答案

每列都有一个索引。我认为使用复合(多列)索引可以获得更好的性能。

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)

关于mysql - 优化慢速 SQL 计数查询和按天分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13265025/

相关文章:

Mysql 结果按每个用户唯一的列表排序

postgresql - 如何使用 PostgreSQL 计算一列中有多少条目是数字的

r - 计算每组的行数并将结果添加到原始数据框

php - 从 mysql "count()"返回计数 0

sql-server - select top 10 ... 和 select top 30 遵循不同的执行计划

mongodb - 为什么索引的方向在 MongoDB 中很重要?

database - 在 mysql 中选择上一行和下一行 - 如何?

java - Jooq Schema 区分大小写

php - "add employee"没有页面重定向的表单

sql - 在未嵌套的 jsonb 列上优化 GROUP BY + COUNT DISTINCT