【问题标题】:How can one optimize this MySQL count algorithm?如何优化这个 MySQL 计数算法?
【发布时间】:2013-05-13 17:42:48
【问题描述】:

我有 2 张桌子;一个是用户,另一个记录用户操作。我想计算每个用户的操作数并将其记录在用户表中。大约有 10 万用户,下面的代码需要 6 个小时!一定有更好的办法!

def calculate_invites():

sql_db.execute("SELECT id, uid FROM users")

for row in sql_db:
    id = row['id']
    uid = row['uid']

    sql1 = "SELECT COUNT(1) FROM actions WHERE uid = %s"
    sql_db.execute(sql1, uid)
    count_actions = sql_db.fetchone()["COUNT(1)"]

    sql = "UPDATE users SET count_actions=%s WHERE uid=%s"
    sql_db.execute(sql, (count_actions, uid))

【问题讨论】:

    标签: python mysql sql count mysql-python


    【解决方案1】:

    您可以将所有这些作为一个语句来完成:

    update users
        set count_actons = (select count(*) from actions a where a.uid = users.uid)
    

    没有 for 循环。没有多个查询。在 SQL 中执行您可以在 SQL 中执行的操作。通常循环遍历行是您希望在数据库中而不是在应用程序中执行的操作。

    【讨论】:

    • update users set count_actons = (select count(1) from actions a where a.uid = users.uid) - 我会将 Count(*) 更改为 Count(1),这样可以节省更多。
    【解决方案2】:

    仅作为替代方案提供,因为 Gordon 的回答可能更快:

    update users
    from (
       select uid, count(*) as num_actions
       from actions
       group by uid
       ) x
    set count_actions = x.num_actions
    where users.uid=x.uid
    

    【讨论】:

    • 。 .这值得一票,因为如果actions(uid) 上没有索引,这个版本会更快。它会扫描表一次,进行聚合(使用外部排序)。我的版本会扫描桌子并做很多小事。有了索引,两者在速度上应该是不相上下的,虽然我觉得我的版本会快一点。
    猜你喜欢
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 2011-02-28
    • 1970-01-01
    • 2010-11-15
    相关资源
    最近更新 更多