我有一个查询运行缓慢,当使用ORDER BY子句。
包含最大行数的表。30.000行。
结果是10行,大约需要0.2秒。
不带"ORDER BY id DESC"需要0.01秒。
我已经研究了其他关于堆栈的帖子,并尝试优化这个脚本,但我的知识已经达到了极限。
我还创建了所有列连接的索引,WHERE, ORDER by.
你认为有什么可以改进的,或者关于如何通过返回更快的结果来订货的想法?
Mysql是这样的
SELECT *
FROM
( SELECT posts.id, posts.createdDateTime, posts.caption, posts.postUrl,
posts.isVideo, posts.paymentType, posts.postPrice, profile.name,
profile.username,
( SELECT COUNT(*)
FROM likes
where likes.postIdFK=posts.id
) as likes,
( SELECT COUNT(*)
FROM likes
where likes.postIdFK=posts.id
AND likes.userIdFK=21643
) as myLike,
( SELECT COUNT(*)
FROM comments
where comments.postIdFK=posts.id
AND comments.deleted=0
) as comments
FROM posts
JOIN users AS profile ON posts.userIdFK=profile.id
WHERE posts.deleted=0
AND profile.deleted=0
AND ( posts.userIdFK IN (
SELECT subscribedToProfileIdFK
FROM
( SELECT userSubscriptions.subscribedToProfileIdFK, max(monthlySubscriptions.endSubscription) endSubscription
FROM userSubscriptions
LEFT JOIN monthlySubscriptions ON monthlySubscriptions.userSubscriptionId=userSubscriptions.id
WHERE userSubscriptions.userIdFK=21643
AND userSubscriptions.quickpayComplete=1
GROUP BY userSubscriptions.id
) t
WHERE (t.endSubscription >= CURDATE())
GROUP BY t.subscribedToProfileIdFK )
OR posts.id IN (
SELECT paidPosts.postIdFK
FROM paidPosts
WHERE paidPosts.userIdFK=21643
)
OR posts.userIDFK=21643 )
) AS row
ORDER BY id DESC
LIMIT 0,10
EXPLAIN看起来像这样
<表类>id select_type 表 类型 possible_keys 键 key_len ref 行额外 tbody><<tr>1 主要 概要文件 ref , 删除删除 1 const 5410 使用临时的;使用filesort 1主要 文章 ref userIdFK,删除 userIdFK 4 admin_slc.profile。id 1 使用在 8物化 paidPosts 所有 userIdFK, postIdFK 空 空 空 5 使用在 6物化 所有 空 空 空 空 14 使用在 7派生 userSubscriptions 指数 userIdFK, quickpayComplete 主要 4 空 15 使用在 7派生 monthlySubscriptions ref userSubscriptionId userSubscriptionId 4 admin_slc.userSubscriptions.id 1 5相关子查询 评论 ref postIdFK,删除 postIdFK 4 admin_slc.posts。id 1 使用在 4相关子查询 喜欢 ref userIdFK, postIdFK postIdFK 4 admin_slc.posts。id 1 使用在 3 相关子查询 喜欢 ref postIdFK postIdFK 4 admin_slc.posts。id 1 使用指数 表类>
您完全可以重写这个查询以从select子句中删除select查询,如下所示:
SELECT * FROM (
SELECT posts.id,
posts.createdDateTime,
posts.caption,
posts.postUrl,
posts.isVideo,
posts.paymentType,
posts.postPrice,
profile.name,
profile.username,
l.cnt as likes,
ml.cnt as myLike,
comm.cnt as comments -- as comments
FROM posts
JOIN users AS profile ON posts.userIdFK=profile.id
LEFT JOIN (SELECT likes.postIdFK, COUNT(*) as cnt FROM likes group by likes.postIdFK) as l
on l.postIdFK=posts.id
LEFT JOIN (SELECT likes.postIdFK, COUNT(*) as cnt FROM likes where likes.userIdFK=21643 group by likes.postIdFK) ml
on ml.postIdFK=posts.id
LEFT JOIN (SELECT comments.postIdFK, COUNT(*) as cnt FROM comments where comments.deleted=0 group by comments.postIdFK) as comm
on comm.postIdFK=posts.id
WHERE posts.deleted=0
AND profile.deleted=0
AND ( posts.userIdFK IN (
SELECT subscribedToProfileIdFK
FROM (SELECT userSubscriptions.subscribedToProfileIdFK,
max(monthlySubscriptions.endSubscription) endSubscription
FROM userSubscriptions
LEFT JOIN monthlySubscriptions ON monthlySubscriptions.userSubscriptionId=userSubscriptions.id
WHERE userSubscriptions.userIdFK=21643
AND userSubscriptions.quickpayComplete=1
GROUP BY userSubscriptions.id) t
WHERE (t.endSubscription >= CURDATE())
-- GROUP BY t.subscribedToProfileIdFK -- this group by is not needed
)
OR exists
(SELECT 1
FROM paidPosts
WHERE paidPosts.userIdFK=21643
AND posts.id = paidPosts.postIdFK)
OR posts.userIDFK=21643
)
) AS row
ORDER BY id DESC
LIMIT 0,10