Select & 在同一查询中更新

Select & update in same query

我有两个 table 用户和用户登录历史记录。我需要报告特定用户登录系统的时间。 table 包含数百万行数据。因此 运行 获取用户登录次数的嵌套查询会花费大量时间。

我正在尝试遍历所有用户并更新登录列。如何在一个查询中执行此操作?

架构是这样的:

users table:

user_logs table:

http://sqlfiddle.com/#!9/dc4149

我运行这个查询

UPDATE users u
SET u.logins = (SELECT COUNT(*) 
                FROM user_logs 
                WHERE userid = u.id) 
LIMIT 1

这不起作用。

有什么方法可以遍历用户并更新他们各自的登录计数?

我尝试使用 PHP 来执行此操作,但由于 table 非常大。一个接一个地做这个需要很长时间。

我可以通过命令行执行此操作吗?

更新应该需要很长时间,尤其是如果您在两个 table 上都有正确的索引。

试试这个:

UPDATE users u
INNER JOIN(SELECT ul.userid,count(1) as cnt FROM user_logs ul GROUP BY ul.userid) u2
 ON(u2.userid = u.id)
SET u.logins = u2.cnt

然后确保您有以下索引:

users - (id,logins)
user_logins - (userid)

如果这没有帮助 - 尝试分两步执行此操作,使用子查询结果构建派生的 table,并通过它进行更新:

CREATE TABLE temp_for_update AS(
SELECT ul.userid,count(1) as cnt
FROM user_logs ul 
GROUP BY ul.userid);

CREATE INDEX YourIndex
ON temp_for_update (userid,cnt);

UPDATE users u
INNER JOIN temp_for_update u2
 ON(u2.userid = u.id)
SET u.logins = u2.cnt

这肯定会更快。

尝试像这样使用更新连接

UPDATE users a 
    JOIN (
SELECT userid, COUNT(*) as count_login 
FROM user_logs 
GROUP BY userid) b ON b.userid = a.id 
SET a.logins = b.count_login;