我有三个表:categories、articles和article_events,其结构如下:
categories: id, name (100,000 rows)
articles: id, category_id (6000 rows)
article_events: id, article_id, status_id (20,000 rows)
每行文章的最高article_events.id描述了每篇文章的当前状态。
我正在返回一个表格,显示每个类别中有多少文章处于最新事件状态_id为'1'。
到目前为止,我的代码是可以运行的,但是在我的表格大小下比较慢(需要10秒)。想知道是否有一种方法可以加速。据我所知,所有的表都有适当的索引。
SELECT c.id,
c.name,
SUM(CASE WHEN e.status_id = 1 THEN 1 ELSE 0 END) article_count
FROM categories c
LEFT JOIN articles a ON a.category_id = c.id
LEFT JOIN (
SELECT article_id, MAX(id) event_id
FROM article_events
GROUP BY article_id
) most_recent ON most_recent.article_id = a.id
LEFT JOIN article_events e ON most_recent.event_id = e.id
GROUP BY c.id
基本上我需要两次加入事件表,因为只要请求status_id和MAX(id)一起,它就会返回它找到的第一个status_id,而不是与MAX(id)行相关联的那个。
有没有什么方法让它更好?还是说我必须用10秒钟来活着?谢谢!
编辑:
这是我查询的EXPLAIN:
ID | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra
---------------------------------------------------------------------------------------------------------------------------
1 | PRIMARY | c | index | NULL | PRIMARY | 4 | NULL | 124044 | Using index; Using temporary; Using filesort
1 | PRIMARY | a | ref | category_id | category_id | 4 | c.id | 3 |
1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 6351 |
1 | PRIMARY | e | eq_ref | PRIMARY | PRIMARY | 4 | most_recent.event_id | 1 |
2 | DERIVED | article_events | ALL | NULL | NULL | NULL | NULL | 19743 | Using temporary; Using filesort
EXPLAIN ...
输出结果。 - vyegorov