我正在运行查询以更新用户的字段,如下所示:
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上运行
答案 0 :(得分:6)
尝试替换为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
版本更快,取决于数据的特征。如果没有建议的索引,这可能会更快。