Select & 在同一查询中更新
Select & update in same query
我有两个 table 用户和用户登录历史记录。我需要报告特定用户登录系统的时间。 table 包含数百万行数据。因此 运行 获取用户登录次数的嵌套查询会花费大量时间。
我正在尝试遍历所有用户并更新登录列。如何在一个查询中执行此操作?
架构是这样的:
users
table:
- id INT(10)
- 用户名 VARCHAR(7)
- 登录 INT(10)
user_logs
table:
- id INT(10)
- 用户 ID INT(10)
- login_date 日期时间(19)
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;
我有两个 table 用户和用户登录历史记录。我需要报告特定用户登录系统的时间。 table 包含数百万行数据。因此 运行 获取用户登录次数的嵌套查询会花费大量时间。
我正在尝试遍历所有用户并更新登录列。如何在一个查询中执行此操作?
架构是这样的:
users
table:
- id INT(10)
- 用户名 VARCHAR(7)
- 登录 INT(10)
user_logs
table:
- id INT(10)
- 用户 ID INT(10)
- login_date 日期时间(19)
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;