2

我有以下表格:

tweets               retweets
-----------------    ----------------
user_id  retweets    user_id (etc...)
-----------------    ----------------
1        0           1
2        0           1
                     1
                     2
                     2

我想计算每个用户的转发次数并相应地更新 tweets.retweets:

UPDATE users 
SET retweets = (
  SELECT COUNT(*) FROM retweets WHERE retweets.user_id = users.user_id
)

我已经两次运行此查询,但它超时(在不是那么大的表上)。我的查询有问题吗?

另请参阅 SQL Fiddle(尽管它显然不允许UPDATE语句):http ://www.sqlfiddle.com/#!2/f591e/1

4

2 回答 2

2

此解决方案应该比使用子查询来获取每个用户的推文计数要快得多(您的相关子查询将为每个用户执行):

UPDATE users a
LEFT JOIN
(
    SELECT user_id, COUNT(1) AS retweet_count
    FROM retweets
    GROUP BY user_id
) b ON a.user_id = b.user_id
SET a.retweets = COALESCE(b.retweet_count, 0)
于 2012-07-21T20:58:53.560 回答
1

如果您的转推表没有动态变化,为什么不首先收集数据,然后像这样更新目标表:

create table retweets_hist AS SELECT COUNT(*) AS retweets,user_id FROM retweets group by user_id;

然后

UPDATE users 
SET retweets = NVL(
  SELECT retweets FROM retweets_hist WHERE retweets_hist.user_id = users.user_id
),0)

如果它是动态的,那么我认为使用触发器会更好。

这里的主要问题是当有一个从未转发过的用户计算它的转发是耗时的。

在回答您的问题时,是的,计数只需要一小部分,但计数从未存在过的东西需要时间!这就是问题!

愿这个有更好的时机:

 UPDATE users 
    SET retweets = NVL(
                       SELECT retweets 
                         FROM retweets 
                        WHERE retweets.user_id = users.user_id),0)
  WHERE EXISTS(select * 
                 FROM retweets 
                WHERE retweets.user_id = users.user_id)

但是话又说回来,您必须将“永不转发”更新为零。

**关键字 EXISTS 在 Oracle 我不知道 mysql 是否支持

于 2012-07-19T19:56:19.353 回答