mysql - INNER JOIN 与 LEFT JOIN 的奇怪性能问题

标签 mysql performance join

我使用的查询与此类似:

SELECT `episodes`.*, IFNULL(SUM(`views_sum`.`clicks`), 0) as `clicks`
FROM `episodes`, `views_sum`
WHERE `views_sum`.`index` = "episode" AND `views_sum`.`key` = `episodes`.`id`
GROUP BY `episodes`.`id`

... 需要 ~0.1s 来执行。但这是有问题的,因为某些 episodes 没有相应的 views_sum 行,因此这些剧集不会包含在结果中。

当相应的 views_sum 行不存在时,我想要的是 NULL 值,因此我尝试使用 LEFT JOIN:

SELECT `episodes`.*, IFNULL(SUM(`views_sum`.`clicks`), 0) as `clicks`
FROM `episodes`
LEFT JOIN `views_sum` ON (`views_sum`.`index` = "episode" AND `views_sum`.`key` = `episodes`.`id`)
GROUP BY `episodes`.`id`

此查询生成相同的列,并且还包括第一个查询中缺少的几行。

但是,第二个查询需要 10 倍的时间!整整一秒。

为什么结果如此相似,但执行时间却相差如此之大?没有任何地方接近 10 倍的行数 — 第一个查询大约有 60 个,第二个查询有 70 个。更不用说额外的 10 行没有views 可以求和!

任何光棚将不胜感激!

(在episodes.idviews_sum.indexviews_sum.key上有索引。)

编辑:

我从上面复制粘贴了 SQL,这里是 EXPLAIN,按顺序:

id  select_type table       type    possible_keys   key         key_len     ref                         rows    Extra
1   SIMPLE      views_sum   ref     index,key       index       27          const                       6532    Using where; Using temporary; Using filesort
1   SIMPLE      episodes    eq_ref  PRIMARY         PRIMARY     4           db102914_itw.views_sum.key  1       Using where

id  select_type table       type    possible_keys   key         key_len     ref                         rows    Extra
1   SIMPLE      episodes    ALL     NULL            NULL        NULL        NULL                        70      Using temporary; Using filesort
1   SIMPLE      views_sum   ref     index,key       index       27          const                       6532 

最佳答案

这是我在多次迭代后最终得出的查询。 (SQL_NO_CACHE 标志在那里,所以我可以测试执行时间。)

SELECT SQL_NO_CACHE e.*, IFNULL(SUM(vs.`clicks`), 0) as `clicks`

FROM `episodes` e

LEFT JOIN
(SELECT * FROM `views_sum` WHERE `index` = "episode") vs
ON vs.`key` = e.`id`

GROUP BY e.`id`

因为 ON 条件 views_sum.index = "episode" 是静态的,即不依赖于它所连接的行,我能够通过首先使用 加入前限制 views_sum 表的子查询。

我的查询现在需要大约 0.2 秒。更好的是,时间不会随着查询的偏移量的增加而增加(与我的第一次 LEFT JOIN 尝试不同)。它保持不变,即使您对 clicks 列进行排序也是如此。

关于mysql - INNER JOIN 与 LEFT JOIN 的奇怪性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4395336/

相关文章:

php - PDO bindParam 变成一条语句?

node.js - 我应该将用户信息放入 JWT token 中,还是只放入用户 ID,然后从数据库中选择信息?

c - 编译器读取代码有什么特定的速度吗?

windows - 无需任何第三方即可自行扩展的 Azure 应用程序的模式是什么?

php - 使用 SQL 语句将三个表连接在一起以从每个表中获取数据

mysql - 查询三张表

mysql - 从表中查看历史记录并根据Mysql中的记录标记记录

php - 在 MySQL 中存储下标和上标值

mysql - SQL 查询 : how to check existence of *multiple* rows and columns with one query

mysql - 按年、月分组时对值进行计数