2

我想要做的是加快这个查询。目前它慢了大约 15 秒以上。r.emailv.sent以及r.idr.viewedr.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;
4

4 回答 4

3

INMySQL 为一个子句中的多个记录使用临时表。尝试

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;
于 2012-08-23T04:58:00.483 回答
2

使用LEFT JOIN而不是NOT IN:为什么..?看这里

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;

为了获得最佳性能,请考虑在表上添加以下索引,最好覆盖索引

ALTER TABLE request ADD INDEX ix1 (email, viewed, saved, top, date);

ALTER TABLE viewing ADD INDEX ix1 (sent);
于 2012-08-23T05:00:26.480 回答
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
于 2012-08-23T04:58:15.563 回答
0

显然 MySQL 存在子查询性能问题

幸运的是,有办法解决这个问题。具体来说,将您的子查询转换为连接,或者在您的特定情况下转换为排除连接

于 2012-08-23T04:58:47.420 回答