我有以下表格:
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小提琴(虽然它显然不允许UPDATE
语句):http://www.sqlfiddle.com/#!2/f591e/1
答案 0 :(得分: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)
答案 1 :(得分: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是否支持它