有没有办法优化此查询?它需要超过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
感谢。
答案 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足够智能,可以自动为您进行优化。
我认为您不能避免文件排序,因为您正在对聚合的结果进行排序,而且无法将其编入索引。