Is there any way to optimize this query? It takes more than 2.5 secs.
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;
I already use caching, so there is no problem in terms of code.
This is the explain sql result:
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
Thanks.
You can improve things by adding an index on
created. This will help serve your WHERE clause:It will probably be advantageous to instead create a covering index on
(created, categories_id)so that all the data required for the query is available in the index.Note that the value of
idis not needed for this query because COUNT only cares if the value is NULL or NOT NULL, butidis defined to be NOT NULL in your table definition. It would probably be a good idea to make this explicit by usingCOUNT(*)orCOUNT(1)instead ofCOUNT(id)as this is guaranteed to give the same result. But I would expect that MySQL is intelligent enough to make this optimization for you automatically.I don’t think that you can avoid the file sort because you are sorting on the result of an aggregation, and this cannot be indexed.