我正在尝试做的是加快此查询速度。目前它的速度大约是15秒以上。 r.email 和 v.sent 以及 r.id , r.viewed 上都有索引和 r.saved 。 EXPLAIN显示两个键都在使用中,但我发现它正在使用Using where; Using temporary; Using filesort
。
有关改进此查询的任何想法吗?
SELECT r.id, r.top, r.email
FROM request as r
WHERE r.viewed = 0 AND r.saved = 0 AND r.email NOT IN (
SELECT v.sent FROM viewing as v WHERE v.sent = r.email
)
GROUP BY r.email
ORDER BY r.top desc, r.date
LIMIT 100;
答案 0 :(得分:3)
MySQL在IN
子句中为多个记录使用临时表。尝试
SELECT r.id, r.top, r.email
FROM request as r
left outer join viewing v on v.sent = r.email
WHERE r.viewed = 0 AND r.saved = 0 AND v.sent is null
GROUP BY r.email
ORDER BY r.top desc, r.date
LIMIT 100;
答案 1 :(得分:1)
使用LEFT JOIN
代替NOT IN
:为什么......?见here
SELECT r.id, r.top, r.email
FROM request as r
LEFT JOIN viewing v
ON r.email= v.sent
WHERE r.viewed = 0 AND
r.saved = 0 AND
v.sent IS NULL
GROUP BY r.email
ORDER BY r.top DESC, r.date
LIMIT 100;
为获得最佳性能,请考虑在表格上添加以下索引,最好是covering indexes:
ALTER TABLE request ADD INDEX ix1 (email, viewed, saved, top, date);
ALTER TABLE viewing ADD INDEX ix1 (sent);
答案 2 :(得分:0)
SELECT
r.id,
r.top,
r.email
FROM
request r
LEFT OUTER JOIN
viewing v
ON
v.sent = r.email
WHERE
r.viewed = 0
AND
r.saved = 0
AND
v.sent IS NULL
GROUP BY
r.email
ORDER BY
r.top DESC, r.date
LIMIT 100
答案 3 :(得分:0)
显然MySQL有subquery performance issues。
幸运的是,有办法解决这个问题。具体来说,将子查询转换为联接,或者在特定情况下转换为exclusion join。