我有一个像这样的简单MySQL表:
CREATE TABLE `logins` (
`user` int(10) NOT NULL,
`time` int(10) NOT NULL,
`ip` varchar(20) NOT NULL,
PRIMARY KEY (`user`,`time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
对于CRON,每24小时,我正在对这个表进行清理,我只保留每个用户IP的唯一登录,即如果某个用户从IP X登录5次,我只保留< strong>最新他使用该IP登录并删除剩余的4个。
这是我的QUERY:
DELETE FROM `logins` WHERE (`user`, `time`) NOT IN(
SELECT `user`, `maxtime`
FROM(
SELECT `user`, MAX(`time`) as `maxtime` FROM `logins` GROUP BY `user`, `ip`
) as `a`
)
这种查询 - 子查询方式有点慢。完成大约需要3秒钟。
然而,内部部分非常快。如果我只遗漏SELECT部分,就像这样:
SELECT `user`, MAX(`time`) as `maxtime` FROM `logins` GROUP BY `user`, `ip`
只需不到0.005秒。
所以我想知道:如果我做了相反的事情会怎样?不是'除了X之外全部删除',而是“选择X,全部删除,重新插入X”?
这可能吗?
这样的事情:
1) SELECT `user`, MAX(`time`) as `maxtime` FROM `logins` GROUP BY `user`, `ip`
/* store this somewhere temporarily */
2) TRUNCATE TABLE `logins`
3) reinsert data from step 1 to `logins`
答案 0 :(得分:2)
使用另一个(临时或非临时)表来插入要保留的数据。截短。然后插回来......
INSERT INTO LoginsTemp
SELECT * FROM Logins WHERE ...;
TRUNCATE Logins;
INSERT INTO Logins
SELECT * FROM LoginsTemp;
答案 1 :(得分:1)
我会用它来删除除用户和ip的每个组合的最新记录之外的所有记录:
DELETE l1.*
FROM
logins l1 INNER JOIN logins l2
ON l1.user=l2.user
AND l1.ip=l2.ip
AND l1.time<l2.time
请参阅小提琴here。