[英]MYSQL Query very slow when using ORDER BY datetime
I have the following query which runs on a social network. 我在社交网络上运行以下查询。 The query fetches posts (like Facebook posts) from a database. 该查询从数据库中获取帖子(例如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
Each post may have or may not have comments. 每个帖子可能有或没有评论。 I want the query to fetch the post with the most recent activity first. 我希望查询首先获取具有最新活动的帖子。 So, if the post has a comment, i take the date of the latest comment. 因此,如果帖子中有评论,我将使用最新评论的日期。 If the post does not have a comment, i take the creation date of the post. 如果帖子没有评论,我将以帖子的创建日期为准。
The job is done by Greatest(P.creation_date, Coalesce(Max(C.date), P.creation_date))
which picks up the greates value between the comments dates (if comments exist) and the post creation date. 该工作由Greatest(P.creation_date, Coalesce(Max(C.date), P.creation_date))
,该工作将在注释日期(如果存在注释)与创建帖子的日期之间获取greates值。
Then, the ORDER BY last_activity DESC
does the sorting job. 然后, ORDER BY last_activity DESC
进行排序。
PROBLEM 问题
The query is really slow. 查询真的很慢。 It takes 8 seconds to run. 运行需要8秒钟。 The posts table has 8K rows and the comments table has 8K rows. posts表具有8K行,comments表具有8K行。
What i don't understand is that if I replace the ORDER BY clause with this ORDER BY P.id_post
it takes 0.5 seconds to run. 我不明白的是,如果我用此ORDER BY P.id_post
替换ORDER BY子句,则需要0.5秒才能运行。 But if I replace the ORDER BY clause with ORDER BY P.creation_date
again it takes 8 seconds. 但是,如果我再次用ORDER BY P.creation_date
替换ORDER BY子句,则需要8秒钟。 It seems that it doesn't like dates... 似乎不喜欢约会...
Additional infos 其他资讯
How can i fix this query to run faster? 如何解决该查询以提高运行速度?
The correlated subqueries in the select clause are probably killing you. select子句中的相关子查询可能会杀死您。 Instead, join to a subquery which computes likes statistics: 相反,请加入一个计算喜欢统计信息的子查询:
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,
t.likes_count,
t.do_i_like
FROM posts P
LEFT JOIN
(
SELECT
post_id,
SUM(CASE WHEN post_type = 'P' THEN 1 ELSE 0 END) AS likes_count,
SUM(CASE WHEN post_type = 'P' AND L.id_profile = 2796
THEN 1 ELSE 0 END) AS do_i_like
FROM likes
GROUP BY post_id
) t
ON t.post_id = P.id_post
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'
ORDER BY
last_activity DESC
LIMIT 41, 10
Also after editing your query I do not see a reason to be using GROUP BY
in the outer query, so I removed it. 另外,在编辑查询后,我看不到在外部查询中使用GROUP BY
的原因,因此我将其删除。 And you should be using indices where appropriate, though my hunch is that my suggestion alone should give a noticeable performance boost. 您应该在适当的地方使用索引,尽管我的直觉是仅凭我的建议就可以显着提高性能。
There is a MAX(C.Date) that would require a group by clause, however it too could be substituted for a subquery I believe: 有一个MAX(C.Date)将需要一个group by子句,但是它也可以代替我认为的子查询:
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,
t.likes_count,
t.do_i_like
FROM posts P
LEFT JOIN
(
SELECT
post_id,
SUM(CASE WHEN post_type = 'P' THEN 1 ELSE 0 END) AS likes_count,
SUM(CASE WHEN post_type = 'P' AND L.id_profile = 2796
THEN 1 ELSE 0 END) AS do_i_like
FROM likes
GROUP BY post_id
) t
ON t.post_id = P.id_post
LEFT JOIN (
SELECT
comments.post_id,
MAX(comments.date) max_c_date
FROM comments
inner join posts ON comments.post_id = posts.id_post
where comments.post_type = 'P' AND
comments.id_profile != posts.id_profile
GROUP BY comments.post_id
) C
ON P.id_post = C.post_id AND
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'
ORDER BY
last_activity DESC
LIMIT 41, 10
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.