提高SQLAlchemy更新效率

2024-05-14 18:07:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两张桌子,用户(~200000)和tweet(~200000) 我需要更新所有的用户,与数量的推文,收藏夹(他们的推文),回复,转发。 这是一个脚本:

@classmethod
def get_user_tweet_counts(cls, user_id):
    return (db_session
        .query(
            func.sum(Tweet.favorite_count).label('favorite_count'),
            func.sum(Tweet.retweet_count).label('retweet_count'),
            func.sum(Tweet.reply_count).label('reply_count'),
            func.count(Tweet.id).label('tweet_count'))
        .filter(Tweet.user_id == user_id)
        .group_by(Tweet.user_id).first())  # This will always be one result, should I query differently?

数据库会话:

^{pr2}$

10分钟循环:

for user in all_users:
    update_count += 1
    aggregation_result = Tweet.get_user_tweet_counts(user.id)
    user.total_tweet_favourites = aggregation_result[0] or 0
    user.total_tweet_retweets = aggregation_result[1] or 0
    user.total_tweet_replies = aggregation_result[2] or 0
    user.tweet_count = aggregation_result[3] or 0
User.save()  # this just calls db_session.commit()
# We only commit the session once to speed things up

用户和Tweet声明如下:

User(Base),Tweet(Base)(来自db_nusession片段)。在

在运行时,python占用了80%的cpu和~600mb内存。我该怎么做才能更好?Tweet在用户_id和它自己的id上有索引


Tags: or用户iddbsessioncountresultlabel
1条回答
网友
1楼 · 发布于 2024-05-14 18:07:45

Here是SQLAlchemy的一个很好的答案。基本上,如果您需要扩展到大量行,您将希望绕过ORM。在

在您的特定情况下,您可以使用SQL聚合编写单个查询以获得相同的结果:

UPDATE users SET
  total_tweet_favourites = aggregated.total_tweet_favourites,
  total_tweet_retweets = aggregated.total_tweet_retweets,
  total_tweet_replies = aggregated.total_tweet_replies,
  tweet_count = aggregated.tweet_count
FROM (
  SELECT
    users.id AS id,
    SUM(tweets.favorite_count) AS total_tweet_favourites,
    SUM(tweets.retweet_count) AS total_tweet_retweets,
    SUM(tweets.reply_count) AS total_tweet_replies,
    COUNT(tweets.id) AS tweet_count
  FROM users JOIN tweets ON tweets.user_id = users.id
  GROUP BY users.id
) aggregated
WHERE users.id = aggregated.id;

要将其转换为SQLAlchemy:

^{pr2}$

相关问题 更多 >

    热门问题