当MySQL没有优化它们时,我应该避免加入吗?

时间:2018-05-16 09:02:57

标签: mysql performance join optimization

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

但是,当事情变得比单个LEFT JOIN更复杂时,我的表现会非常糟糕。

今天我刚刚重写了JOIN查询,其执行时间为600秒 采用不同的方法: SELECT(SELECT ... WHERE ID = X.ID)FROM X SELECT ... WHERE Y IN(SELECT ...) 现在它以0.0027秒结束。

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

1 个答案:

答案 0 :(得分:2)

LEFT JOIN 可能,但并非总是如此,强行先查看“左”表。

JOINs(但不是LEFT JOINs)加上触摸一个表的WHERE,为优化工具提供了强大,可靠的提示,可以查看该表第一

JOIN,加上WHERE触及多个表格 - 优化工具有时会选择正确的“第一个”表格,有时则不会。

优化器通常从一个表中获取行(无论选择哪个最好开始),然后执行NLJ(嵌套循环连接)。这意味着一次一行地进入下一个表。这种“覆盖面”需要一个很好的指数。

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

“爆炸 - 内爆”袭击了很多人。这是JOINGROUP BY的位置。分组主要是为了破坏由连接创建的大量行。有时,“派生”表可以是一个很好的优化。 (这是查询的手动重新制定。)

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

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

我应该絮絮叨叨吗?我怀疑我是否覆盖了1/4以上的案例。所以,我同意@leftjoin。

以下是一些简单的提示:http://mysql.rjweb.org/doc.php/index_cookbook_mysql