选择&在同一查询

时间:2016-06-01 12:46:48

标签: mysql procedure

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

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

架构是这样的:

users表:

  • id INT(10)
  • 用户名VARCHAR(7)
  • 登录INT(10)

user_logs表:

  • id INT(10)
  • userid INT(10)
  • login_date DATETIME(19)

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

我正在运行此查询

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

这不起作用。

有什么方法可以循环用户和&更新各自的登录计数?

我尝试用PHP做这个,但因为表非常大。这样做1比1需要很长时间。

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

2 个答案:

答案 0 :(得分:1)

更新应该花费很长时间,特别是如果您在两个表上都有适当的索引。

试试这个:

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)

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

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

这应该更快。

答案 1 :(得分:1)

尝试使用像

这样的更新连接
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;