1

有没有办法优化这个查询?它需要超过 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

谢谢。

4

1 回答 1

2

您可以通过在created. 这将有助于为您的 WHERE 子句提供服务:

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

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

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

我不认为您可以避免文件排序,因为您正在对聚合结果进行排序,而这无法被索引。

于 2012-04-28T21:40:19.487 回答