我正在运行查询以更新用户字段,如下所示:
UPDATE Members SET abc = abc + 1 where Members.id in (
SELECT DISTINCT(memberId) FROM Events WHERE Events.createdAt > "2017-08-06 13:10:00";
令人震惊的是,有大约500个成员,这个查询运行40秒。。。
所以分解:
SELECT DISTINCT(memberId) FROM Events WHERE Events.createdAt > "2017-08-06 13:10:00"
运行0.1秒,只有39行匹配。
会员总数只有大约500人。我不明白为什么要花那么长时间。。。我遗漏了什么吗?
我在用mysql 5.6运行RDS
最佳答案
尝试用exists
替换:
UPDATE Members m
SET abc = abc + 1
WHERE EXISTS (SELECT 1
FROM events e
WHERE e.memberId = m.id AND
e.createdAt > '2017-08-06 13:10:00'
);
为了提高性能,需要在
events(memberId, createdAt)
上建立索引。我猜MySQL对
Members
中的每一行都运行一次子查询。这与您的计时一致--0.1秒*~500行约为50秒,与40秒相差不远。对于
SELECT
s,这是几个版本之前修复的。也许这个问题仍然存在于非SELECT
查询中。你也可以这样写:
UPDATE Members m JOIN
(SELECT DISTINCT e.memberId
FROM events e
WHERE e.createdAt > '2017-08-06 13:10:00'
) e
ON e.memberId = m.id
SET abc = abc + 1 ;
这是否比
exists
版本快,取决于数据的特性。如果没有建议的指数,这可能会更快。关于mysql - 40秒奇怪的SQL性能难题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45533029/