[英]MYSQL Query very slow when using ORDER BY datetime
我在社交網絡上運行以下查詢。 該查詢從數據庫中獲取帖子(例如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
每個帖子可能有或沒有評論。 我希望查詢首先獲取具有最新活動的帖子。 因此,如果帖子中有評論,我將使用最新評論的日期。 如果帖子沒有評論,我將以帖子的創建日期為准。
該工作由Greatest(P.creation_date, Coalesce(Max(C.date), P.creation_date))
,該工作將在注釋日期(如果存在注釋)與創建帖子的日期之間獲取greates值。
然后, ORDER BY last_activity DESC
進行排序。
問題
查詢真的很慢。 運行需要8秒鍾。 posts表具有8K行,comments表具有8K行。
我不明白的是,如果我用此ORDER BY P.id_post
替換ORDER BY子句,則需要0.5秒才能運行。 但是,如果我再次用ORDER BY P.creation_date
替換ORDER BY子句,則需要8秒鍾。 似乎不喜歡約會...
其他資訊
如何解決該查詢以提高運行速度?
select子句中的相關子查詢可能會殺死您。 相反,請加入一個計算喜歡統計信息的子查詢:
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
另外,在編輯查詢后,我看不到在外部查詢中使用GROUP BY
的原因,因此我將其刪除。 您應該在適當的地方使用索引,盡管我的直覺是僅憑我的建議就可以顯着提高性能。
有一個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.