I have two tables:
CREATE TABLE `articles` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(1000) DEFAULT NULL,
`last_updated` datetime DEFAULT NULL
First of all, I would recommend reading the article 3 ways MySQL uses indexes.
And now, when you know the basics, you can optimize this particular query.
MySQL can not use index for ordering, it just can output data in an order of an index. Since MySQL uses nested loops for joining, the field you want to order by should be in the first table in the join (you see the order of join in EXPLAIN results, and can affect it by creating specific indexes and (if it does not help) by forcing required indexes).
Another important thing is that before ordering you fetch all columns for all filtered rows from a
table and then skip probably most of them. It is much more effifient to get a list of required row ids and fetch only those rows.
To make this work you will need a covering index (deleted, comment_cnt, last_updated)
on table a
, and now you can rewrite the query as follows:
SELECT *
FROM (
SELECT a.id
FROM articles AS a,
JOIN article_categories AS c
ON a.id = c.article_id AND c.category_id = 78
WHERE a.comment_cnt > 0 AND a.deleted = 0
ORDER BY a.last_updated
LIMIT 100, 20
) as ids
JOIN articles USING (id);
P.S. Your table definition for table a
does not contain comment_cnt
column ;)