【问题标题】:Speeding up WHERE NOT IN MySQL Query加速 WHERE NOT IN MySQL 查询
【发布时间】:2012-08-18 13:46:32
【问题描述】:

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

【问题讨论】:

  • 这是一个相关的子查询,这意味着它将针对正在考虑的r 的每一行进行评估。尝试改写为普通连接。
  • 子查询上的WHERE 条件没有理由存在。如果你删除了它,MySQL 会优化掉子查询,因为它不再依赖于外部查询。

标签: php mysql sql select


【解决方案1】:

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;

【讨论】:

  • 似乎我只看到了 12 行但有数千行。在选择中检查了 r.viewed 和 r.saved = 0 并且返回了数千个。还检查了查看表,大多数 v.sent 都是空的。该字段设置为不允许为空。
  • 这很奇怪。见this simplified example。也许你可以增强它。
【解决方案2】:

使用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);

【讨论】:

    【解决方案3】:
    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
    

    【讨论】:

      【解决方案4】:

      显然 MySQL 有 subquery performance issues

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

      【讨论】:

        猜你喜欢
        • 2014-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-08
        相关资源
        最近更新 更多