mySQL查询优化,范围/复合索引/分组依据

时间:2012-01-17 02:00:12

标签: mysql optimization

查询的基本形式是:

EXPLAIN SELECT SUM(impressions) as impressions, SUM(clicks) as clicks, SUM(cost) as cost, SUM(conversions) as conversions, keyword_id FROM `keyword_track` WHERE user_id=1 AND campaign_id=543 AND `recorded`>1325376071 GROUP BY keyword_id

似乎我可以索引说user_id,campaign_id和keyword_id并获得没有文件排序的GROUP BY,尽管记录的范围索引确实会更积极地减少行数,这个例子有很大的范围但其他查询的时间范围要小得多。

表格如下:

CREATE TABLE IF NOT EXISTS `keyword_track` (
`track_id` int(11) NOT NULL auto_increment,
`user_id` int(11) NOT NULL,
`campaign_id` int(11) NOT NULL,
`adgroup_id` int(11) NOT NULL,
`keyword_id` int(11) NOT NULL,
`recorded` int(11) NOT NULL,
`impressions` int(11) NOT NULL,
`clicks` int(11) NOT NULL,
`cost` decimal(10,2) NOT NULL,
`conversions` int(11) NOT NULL,
`max_cpc` decimal(3,2) NOT NULL,
`quality_score` tinyint(4) NOT NULL,
`avg_position` decimal(2,1) NOT NULL,
PRIMARY KEY  (`track_id`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;

我已经离开了我目前所拥有的任何钥匙。基本上问题是,最好的方法是在至少为campaign_id建立索引并且理想情况下不需要文件排序的范围内获取索引(尽管这可能是在记录时间内获得范围索引的可接受的权衡)。 / p>

2 个答案:

答案 0 :(得分:2)

每当我们对表的不同属性进行范围约束和约束排序时,我们可以利用结果集的快速过滤或快速排序,但不能同时使用。

我的回答是...... 如果您的范围约束确实减少了大量记录并导致一小组行输出,则更好的索引支持范围约束。即(user_id,campaign_id,记录)

如果不是,我的意思是如果在确认了范围条件并且应该对其进行排序后确实存在大量行,那么请寻找支持排序的索引。 即(user_id,campaign_id,key_id)

为了更好地理解这一点,请看下面的链接,其中非常清楚地解释了同样的事情。

http://explainextended.com/2009/04/01/choosing-index/

答案 1 :(得分:1)

在这种情况下,您的最佳索引是复合索引user_id + campaign_id + recorded

虽然只要您与>recorded字段进行group by比较,但这根本不会有助于避免使用。