首页 > 解决方案 > 当 MySQL 不优化它们时,我应该避免 JOIN 吗?

问题描述

在大学 SQL 课程关系数据库中,都是关于表之间的 JOINS 的。所以我采用了一般的方法,首先做所有必要的 JOINS,然后选择数据,用 WHERE 过滤,必要时用 GROUP BY。这样代码和逻辑就很简单了。

但很多时候,当事情变得比单个 LEFT JOIN 更复杂时,我的表现会很差。

今天我只是重写了 JOIN 查询,这 600 秒的执行时间到不同的方法: SELECT (SELECT ... WHERE ID = X.ID) FROM XSELECT ... WHERE Y IN (SELECT ...) 现在它完成了在 0.0027 秒内。

我很沮丧,我在我加入的字段上使用索引,但性能太差了......

标签: mysqlperformancejoinoptimization

解决方案


LEFT JOIN 可能但并不总是强制首先查看“左”表。

JOINs(但不是LEFT JOINs)加上WHERE触及一张表的 a 给优化器一个强大、可靠的提示,让您先查看该一张表。

JOIN,加上一个WHERE感人的多表——优化器有时会选择正确的“第一个”表,有时不会。

优化器通常从一个表中获取行(从它选择的最佳开始),然后执行 NLJ(嵌套循环连接)。这意味着一次进入下一个表一行。这个“范围”需要一个好的索引。

IN ( SELECT ... ),在版本中是非常不理想的。现在,它可能会变成一个“半连接”,就像一个EXIST ( SELECT ... )并且非常有效。有时手动这样做是有益的。

“Explode-Implode”打击了很多人。这是有 aJOIN和 a 的地方GROUP BY。分组主要是为了内爆连接创建的大量行。有时,“派生”表可能是一个很好的优化。(这是查询的手动重新表述。)

通常LEFT JOIN用于聚合的 a 可以像这样折叠:SELECT ..., ( SELECT SUM(foo) FROM ... ) AS foos, ...,从而减轻爆炸内爆。

不了解“复合”索引的好处可能是这个论坛上最常见的问题。

我要继续闲逛吗?我怀疑我是否涵盖了超过 1/4 的案例。所以,我同意@leftjoin。

这里有一些简单的提示:http: //mysql.rjweb.org/doc.php/index_cookbook_mysql


推荐阅读