MySQL慢查询:计算文章,按类别分组,任何优化方式?

时间:2012-04-28 21:32:53

标签: mysql query-optimization explain

有没有办法优化此查询?它需要超过2.5秒。

SELECT articles.categories_id,
    COUNT(articles.id) AS count
FROM articles
WHERE articles.created >= DATE_SUB(NOW(), INTERVAL 48 HOUR)
GROUP BY articles.categories_id
ORDER BY count DESC

CREATE TABLE IF NOT EXISTS `articles` (
  `id` int(11) NOT NULL,
  `categories_id` int(11) NOT NULL,
  `feeds_id` int(11) NOT NULL DEFAULT '0',
  `users_id` int(11) NOT NULL DEFAULT '1',
  `title` varchar(255) CHARACTER SET utf8 NOT NULL,
  `sefriendly` varchar(255) CHARACTER SET utf8 NOT NULL,
  `body` text CHARACTER SET utf8,
  `source` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
  `created` datetime NOT NULL,
  `edited` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `fingerprint` varchar(32) CHARACTER SET utf8 NOT NULL,
  `type` int(1) NOT NULL DEFAULT '1' COMMENT '1 => Feed fetched article\n2 => User submitted article',
  `description` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
  `keywords` text CHARACTER SET utf8,
  `status` int(1) NOT NULL DEFAULT '0' COMMENT '0 => Passive\n1 => Active\n2 => Pending',
  PRIMARY KEY (`id`),
  KEY `categories_id` (`categories_id`) USING BTREE,
  KEY `feeds_id` (`feeds_id`) USING BTREE,
  KEY `users_id` (`users_id`) USING BTREE,
  KEY `fingerprint` (`fingerprint`) USING BTREE,
  KEY `title` (`title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci ROW_FORMAT=COMPACT;

我已经使用了缓存,因此在代码方面没有问题。

这是解释sql结果:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  articles    index   NULL    categories_id   4   NULL    120411  Using where; Using temporary; Using file sort

感谢。

1 个答案:

答案 0 :(得分:2)

您可以通过在created上添加索引来改进。这将有助于提供WHERE子句:

WHERE articles.created >= DATE_SUB(NOW(), INTERVAL 48 HOUR)

(created, categories_id)上创建覆盖索引可能是有利的,这样查询所需的所有数据都可以在索引中使用。

请注意,此查询不需要id的值,因为COUNT只关注值是NULL还是NOT NULL,但id在表定义中定义为NOT NULL。使用COUNT(*)COUNT(1)代替COUNT(id)来明确这一点可能是个好主意,因为这可以保证给出相同的结果。但我希望MySQL足够智能,可以自动为您进行优化。

我认为您不能避免文件排序,因为您正在对聚合的结果进行排序,而且无法将其编入索引。