MySQL优化子查询&按汇总排序

时间:2016-01-26 10:54:07

标签: mysql sql sql-optimization

我正在收集一些数据(带有主题标签的推文),并努力创建具有以下表格结构的统计数据:

enter image description here

我的统计目标是显示每个推文有多少孩子和多少印象

查询:

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:计算总推文,其中is_retweet = parent.tweet_id

impression:parent.user_follower + sum user_follewer其中is_retweet = parent.tweet_id

我的查询在获取childimpression时速度太慢而且我不知道如何优化:(但是,真正的问题是当我想在展示中找到前十大影响力时,{ {1}}看起来很愚蠢。

我希望这有助于简化此查询:)

2 个答案:

答案 0 :(得分:2)

我首先将子查询从选择列表中移出到from子句作为派生表。您只需要一个子查询,因为2个子查询具有相同的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

可以使用适当的索引进一步增强查询,但我没有足够的时间来继续查询。但是,外部查询中字段的复合索引,其中条件似乎是一个好的起点 - 如果您还没有这样做。

不幸的是,要获得前10个展示,您必须按计算展示字段和限制条款使用订单。它不会真正加快查询速度,因为mysql必须先计算所有展示次数才能进行排序。

答案 1 :(得分:0)

这是您的查询(基本上):

testCompile('org.robolectric:robolectric:3.0') {
    //exclusions due to android.jar conflict
    exclude module: 'httpclient'
    exclude module: 'commons-logging'
}

在许多情况下,这可能是编写查询的最佳方式。您需要的是索引: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; tweet(twee_status, is_retweet, is_vaforite, is_replay, tweet_time, tweet_id)。我认为这些将删除推文表上的任何聚合或排序,处理索引中的所有过滤和计算。