MySQL 通过聚合优化子查询和排序

标签 mysql sql sql-optimization

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

enter image description here

我的统计目标是显示每条推文有多少 child 和多少印象

查询:

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

印象:parent.user_follower + sum user_follewer where is_retweet = parent.tweet_id

我的查询在获取 childimpression 时太慢了,我不知道如何优化 :(。但是,真正的问题是当我想找到前 10 名时影响基于印象,ORDER BY impression 看起来很愚蠢。

我希望这一切都有助于简化这个查询:)

最佳答案

我将从将子查询从选择列表移到作为派生表的 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

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

不幸的是,要仅获得前 10 名展示次数,您必须使用按计算展示次数字段和限制子句排序。它不会真正加快查询速度,因为 mysql 在进行排序之前必须计算所有展示次数。

关于MySQL 通过聚合优化子查询和排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35012170/

相关文章:

mysql - 插入没有 id postgreSQL 的命令

sql-server - SQL 服务器 : Selective XML Index not being efficiently used

MySQL LIMIT 关键字优化问题

mysql - 将 IN 子查询重写为 JOIN

c# - 将列添加到数据集以用作 XML 父节点

mysql - 我想在 mysql 中使用 if -else 语句

mysql - 如何在删除其中一个表的记录时保持两个表的数据一致?

java - Spring 3 DataSourceTransactionManager 在将事务获取到 MySQL 时偶尔超时

java - Hibernate Projection 将结果返回为对象

sql - 在联接表中计数的最佳方法