表格如下:
CREATE TABLE `tweet_tweet` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(256) NOT NULL,
`created_at` datetime NOT NULL,
`created_date` date NOT NULL,
...
`positive_sentiment` decimal(5,2) DEFAULT NULL,
`negative_sentiment` decimal(5,2) DEFAULT NULL,
`entity_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `tweet_tweet_entity_created` (`entity_id`,`created_at`)
) ENGINE=MyISAM AUTO_INCREMENT=1097134 DEFAULT CHARSET=utf8
查询的解释如下:
mysql> explain SELECT `tweet_tweet`.`entity_id`,
STDDEV_POP(`tweet_tweet`.`positive_sentiment`) AS `sentiment_stddev`,
AVG(`tweet_tweet`.`positive_sentiment`) AS `sentiment_avg`,
COUNT(`tweet_tweet`.`id`) AS `tweet_count`
FROM `tweet_tweet`
WHERE `tweet_tweet`.`created_at` > '2010-10-06 16:24:43'
GROUP BY `tweet_tweet`.`entity_id` ORDER BY `tweet_tweet`.`entity_id` ASC;
+----+-------------+-------------+------+---------------+------+---------+------+---------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+------+---------------+------+---------+------+---------+----------------------------------------------+
| 1 | SIMPLE | tweet_tweet | ALL | NULL | NULL | NULL | NULL | 1097452 | Using where; Using temporary; Using filesort |
+----+-------------+-------------+------+---------------+------+---------+------+---------+----------------------------------------------+
1 row in set (0.00 sec)
每天大约有300,000行添加到表中。该查询现在运行大约4秒,但我想将其降低到大约1秒钟,我担心随着时间的推移,查询将呈指数级增长。 tweet_tweet中的总行数目前只有1M多一点,但它会快速增长。
有关优化此事的任何想法?我还需要更多索引吗?我应该使用像Cassandra而不是MySQL吗? =)
答案 0 :(得分:1)
您可以尝试重新排序索引中的字段(即KEY tweet_tweet_entity_created (created_at, entity_id)
。这将允许mysql使用索引来减少需要分组和排序的实际行数。)
答案 1 :(得分:0)
你没有使用索引tweet_tweet_entity_created。将您的查询更改为:
explain SELECT `tweet_tweet`.`entity_id`,
STDDEV_POP(`tweet_tweet`.`positive_sentiment`) AS `sentiment_stddev`,
AVG(`tweet_tweet`.`positive_sentiment`) AS `sentiment_avg`,
COUNT(`tweet_tweet`.`id`) AS `tweet_count`
FROM `tweet_tweet` FORCE INDEX (tweet_tweet_entity_created)
WHERE `tweet_tweet`.`created_at` > '2010-10-06 16:24:43'
GROUP BY `tweet_tweet`.`entity_id` ORDER BY `tweet_tweet`.`entity_id` ASC;
您可以在MySQL手册http://dev.mysql.com/doc/refman/5.1/en/index-hints.html
中阅读有关索引提示的更多信息有时MySQL的查询优化器需要一些帮助。
答案 2 :(得分:0)
我建议至少在created_at中添加一个额外的索引。我不知道在聚合列中添加索引是否也会加快速度。
答案 3 :(得分:0)
如果您的mysql版本为5.1或更高版本,则可以考虑对大型表进行分区选项。