MySQL优化子查询&;按合计订购
我正在收集一些数据(带有hashtag的tweet),并使用以下表格结构创建一个stats: 我的统计目标是显示每条推文有多少孩子和多少印象 查询:MySQL优化子查询&;按合计订购,mysql,sql,sql-optimization,Mysql,Sql,Sql Optimization,我正在收集一些数据(带有hashtag的tweet),并使用以下表格结构创建一个stats: 我的统计目标是显示每条推文有多少孩子和多少印象 查询: SELECT parent.tweet_id, parent.tweet_text, parent.tweet_time, parent.tweet_image, parent.user_id, parent.user_name, parent.user_follower, parent.user_following, parent.is_ret
SELECT parent.tweet_id, parent.tweet_text, parent.tweet_time, parent.tweet_image, parent.user_id, parent.user_name, parent.user_follower, parent.user_following, parent.is_retweet, parent.is_favorite, parent.is_reply,
(
SELECT COUNT(tweet_id)
FROM tweet
WHERE tweet_status = 1 && user_follower > 0 && is_retweet = parent.tweet_id
) as child,
(
SELECT (COALESCE(SUM(user_follower),0) + parent.user_follower)
FROM tweet WHERE tweet_status = 1 && user_follower > 0 && is_retweet = parent.tweet_id
) as impression
FROM tweet AS parent
WHERE parent.tweet_status = 1 AND parent.is_retweet = 0 AND parent.is_favorite = 0 AND parent.is_reply = 0
ORDER BY parent.tweet_time DESC
child
:计算推文总数,其中是\u retweet=parent.tweet\u id
impression
:parent.user\u follower+sum user\u follower,其中是\u retweet=parent.tweet\u id
我的查询在获取子项
和印象
时太慢,我不知道如何优化:(.但是,真正的问题是,当我想根据印象找到前十大影响时,按印象排序
看起来很愚蠢
我希望这些都有助于简化此查询:)我首先将子查询作为派生表从select列表移动到from子句中。您只需要一个子查询,因为这两个子查询具有相同的where条件,包括连接条件。派生表应按is_retweet分组,因为它表示父子关系。显然,印象仍然必须在选择列表中计算,因为派生表只能提供转发的追随者
SELECT parent.tweet_id, parent.tweet_text, parent.tweet_time, parent.tweet_image, parent.user_id, parent.user_name, parent.user_follower, parent.user_following, parent.is_retweet, parent.is_favorite, parent.is_reply,
COALESCE(t.child,0) as child,
COALESCE(t.sum_child_follower,0) + parent.user_follower as impression
FROM tweet AS parent
LEFT JOIN
(
SELECT is_retweet, COUNT(tweet_id) as child, SUM(user_follower) as sum_child_follower
FROM tweet
WHERE tweet_status = 1 && user_follower > 0
GROUP BY is_retweet
) as t ON t.is_retweet=parent.tweet_id
WHERE parent.tweet_status = 1 AND parent.is_retweet = 0 AND parent.is_favorite = 0 AND parent.is_reply = 0
ORDER BY parent.tweet_time DESC
可以使用适当的索引进一步增强查询,但我没有足够的索引。但是,外部查询的where条件中的字段上的复合索引似乎是一个很好的开始——如果您还没有这样做的话
不幸的是,为了只获得前10个印象,您必须使用order by calculated impression字段和limit子句。它不会真正加快查询速度,因为mysql必须先计算所有印象,然后才能进行排序。这是您的查询(基本上):
在许多情况下,这可能是编写查询的最佳方式。你需要的是索引:
tweet(tweee\u状态、is\u转发、is\u vaforite、is\u回放、tweet\u时间、tweet\u id)
和tweet(is\u转发、tweet\u状态、用户跟随者)
。我认为这将删除tweet表上的任何聚合或排序,处理索引中的所有筛选和计算。请提供所有受影响表上的现有索引列表,并为您的查询提供解释的输出。我将首先将子查询从select列表移动到from子句中作为派生表。非常感谢,我使用您的查询,并且我有更好的速度:)顺便说一句,如何使用适当的索引?我使用ALTER TABLEtweet
添加索引(tweet\u id
);当然,您的子查询需要返回用于连接的is_retweet列?@AdrianYoan使用您最喜欢的mysql管理应用程序添加/删除索引,通过sql手动添加索引没有意义。添加新索引后,通过运行解释来测试查询是否使用了该索引。在is_retweet上创建索引可能有助于子查询,但不会有助于外部查询。我不知道您的数据,也不知道您需要在这个特定表上运行的其他查询,也不知道这个查询的解释,所以我不愿意建议使用确切的索引。少量的实验/阅读和大量的解释可以发挥神奇的作用。@Shadow顺便说一句,我尝试解释您的查询
和
SELECT parent.*,
(SELECT COUNT(*)
FROM tweet t
WHERE t.tweet_status = 1 AND t.user_follower > 0 AND
t.is_retweet = parent.tweet_id
) as child,
(SELECT (COALESCE(SUM(t.user_follower), 0) + parent.user_follower)
FROM tweet t
WHERE t.tweet_status = 1 AND t.user_follower > 0 AND
t.is_retweet = parent.tweet_id
) as impression
FROM tweet AS parent
WHERE parent.tweet_status = 1 AND parent.is_retweet = 0 AND
parent.is_favorite = 0 AND parent.is_reply = 0
ORDER BY parent.tweet_time DESC;