MySQL优化子查询&;按合计订购

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

我正在收集一些数据(带有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_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 TABLE
tweet
添加索引(
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;