【发布时间】:2017-10-12 00:01:53
【问题描述】:
我有以下在社交网络上运行的查询。该查询从数据库中获取帖子(如 Facebook 帖子)。
SELECT P.*,
P.id_post id_p,
PM.meta_content video_title,
PM2.meta_content video_views,
PM3.meta_content racebooking_views,
Greatest(P.creation_date, Coalesce(Max(C.date), P.creation_date)) AS
last_activity,
P.creation_date creation_date,
(SELECT Count(*)
FROM likes
WHERE post_id = P.id_post
AND post_type = 'P')
likes_count,
(SELECT Count(*)
FROM likes L
WHERE post_id = P.id_post
AND post_type = 'P'
AND L.id_profile = 2796)
do_i_like
FROM posts P
LEFT JOIN comments C
ON P.id_post = C.post_id
AND C.post_type = 'P'
AND C.id_profile != P.id_profile
LEFT JOIN post_meta PM
ON PM.id_post = P.id_post
AND PM.meta_type = 'T'
LEFT JOIN post_meta PM2
ON PM2.id_post = P.id_post
AND PM2.meta_type = 'V'
LEFT JOIN post_meta PM3
ON PM3.id_post = P.id_post
AND PM3.meta_type = 'W'
GROUP BY P.id_post
ORDER BY last_activity DESC
LIMIT 41, 10
每个帖子可能有也可能没有 cmets。 我希望查询首先获取具有最新活动的帖子。 所以,如果帖子有评论,我会选择最新评论的日期。如果帖子没有评论,我会以帖子的创建日期为准。
这项工作由Greatest(P.creation_date, Coalesce(Max(C.date), P.creation_date)) 完成,它获取 cmets 日期(如果存在 cmets)和帖子创建日期之间的最大价值。
然后,ORDER BY last_activity DESC 进行排序工作。
问题
查询真的很慢。运行需要 8 秒。 posts 表有 8K 行,cmets 表有 8K 行。
我不明白的是,如果我用这个ORDER BY P.id_post 替换 ORDER BY 子句,它需要 0.5 秒才能运行。但是,如果我再次用ORDER BY P.creation_date 替换 ORDER BY 子句,则需要 8 秒。好像不喜欢约会……
其他信息
- posts 表在 creation_date 上有一个索引。
- cmets 表在日期上有一个索引
- 服务器在 CentOS Linux 6.6 上运行 LAMP
- 我在 SO like this one 上尝试了其他解决方案,但没有奏效
如何修复此查询以更快地运行?
【问题讨论】:
-
您是否尝试在列
creation_date上创建索引? -
@YuJiaao 在问题中我写了“posts table has an index on creation_date”。你是这个意思还是别的意思?
-
您使用 group by
last_activity,但 last_activity 是动态生成的,我认为索引在这种情况下没有帮助,也许添加last_activity作为帖子表的列?