MySQL JOIN 顺序与性能优化


发布日期 : 2019-03-25 05:24:36 UTC

访问量: 10 次浏览

MySQL SQL JOIN 在性能方面应该放置在特定顺序吗

在 MySQL 中,当我们需要从两个或多个表中读取和比较数据时,我们通常使用 JOIN 语句。在一些情况下,JOIN 语句在执行查询时可能会非常缓慢,因此我们一般会问一个问题:SQL JOIN 在性能方面应该放置在特定顺序吗?本文将探讨这个问题,并为您提供一些帮助优化查询的方法。

阅读更多:MySQL 教程

SQL JOIN 的基础知识

在使用 JOIN 语句之前,我们需要了解两个或多个表之间的关系。在 MySQL 中,表之间的关系可以是一对一、一对多或多对多。下面是三种常见的 JOIN 类型:

INNER JOIN

INNER JOIN 是从两个表中选择匹配的行,这些行在两个表之间都有比较值的联接方式。例如,考虑以下两个表:

Table A:
+----+--------+
| id |  name  |
+----+--------+
|  1 | Alice  |
|  2 | Bob    |
|  3 | Carol  |
+----+--------+

Table B:
+-----+------+
| id  | age  |
+-----+------+
|  1  |  25  |
|  2  |  30  |
|  4  |  35  |
+-----+------+

我们可以使用以下 INNER JOIN 查询语句:

SELECT * FROM A
INNER JOIN B ON A.id=B.id;

该语句将返回包含 id 为 1 和 2 的行的结果:

+-----+-------+-----+------+
| id  | name  | id  | age  |
+-----+-------+-----+------+
|  1  | Alice |  1  |  25  |
|  2  | Bob   |  2  |  30  |
+-----+-------+-----+------+

LEFT JOIN

LEFT JOIN 是从左边表中选择所有的行,然后将右边表中与左边表中的某些行匹配的行连接起来。例如,考虑以下两个表:

Table A:
+----+--------+
| id |  name  |
+----+--------+
|  1 | Alice  |
|  2 | Bob    |
|  3 | Carol  |
+----+--------+

Table B:
+-----+------+
| id  | age  |
+-----+------+
|  1  |  25  |
|  2  |  30  |
|  4  |  35  |
+-----+------+

我们可以使用以下 LEFT JOIN 查询语句:

SELECT * FROM A
LEFT JOIN B ON A.id=B.id;

该语句将返回左边表中的所有行,如果左边表中的行存在匹配的行,则将右边表中的行连接起来。结果如下:

+-----+-------+------+------+
| id  | name  | id   | age  |
+-----+-------+------+------+
|  1  | Alice |   1  |  25  |
|  2  | Bob   |   2  |  30  |
|  3  | Carol | NULL | NULL |
+-----+-------+------+------+

RIGHT JOIN

RIGHT JOIN 是从右边表中选择所有的行,然后将左边表中与右边表中的某些行匹配的行连接起来。它与 LEFT JOIN 相反。例如,考虑以下两个表:

Table A:
+----+--------+
| id |  name  |
+----+--------+
|  1 | Alice  |
|  2 | Bob    |
|  3 | Carol  |
+----+--------+

Table B:
+-----+------+
| id  | age  |
+-----+------+
|  1  |  25  |
|  2  |  30  |
|  4  |  35  |
+-----+------+

我们可以使用以下 RIGHT JOIN 查询语句:

SELECT * FROM A
RIGHT JOIN B ON A.id=B.id;

该语句将返回右边表中的所有行,如果右边表中的行存在匹配的行,则将左边表中的行连接起来。结果如下:

+------+-------+-----+------+
| id   | name  | id  | age  |
+------+-------+-----+------+
|    1 | Alice |   1 |  25  |
|    2 | Bob   |   2 |  30  |
| NULL | NULL  |   4 |  35  |
+------+-------+-----+------+

SQL JOIN 的优化

当使用 JOIN 语句时,我们需要优化查询以提高性能。以下是一些建议:

选择正确的 JOIN 类型

需要根据表之间的关系以及需要选择的行数选择正确的 JOIN 类型。如果表之间具有一对一关系,则使用 INNER JOIN。如果左边表中的所有行都需要,在右边表中有匹配的行,则使用 LEFT JOIN。如果右边表中的所有行都需要,在左边表中有匹配的行,则使用 RIGHT JOIN

定义索引

在根据列进行 JOIN 时,对列定义索引以提高性能。如果没有索引,则需要扫描整个表来查找匹配行。索引有助于减少 JOIN 操作的时间。

选择正确的 JOIN 顺序

通常情况下,不同的 JOIN 顺序会产生不同的结果,但它们可能会影响到性能,尤其是在使用大型表时。我们可以尝试不同的 JOIN 顺序来找到最优的性能。

以下是一个例子:考虑以下三个表:

Table A:
+----+----------+
| id |  name    |
+----+----------+
|  1 | Alice    |
|  2 | Bob      |
|  3 | Carol    |
+----+----------+

Table B:
+-----+---------+
| id  |  city   |
+-----+---------+
|  1  | London  |
|  2  | Paris   |
+-----+---------+

Table C:
+-----+-------+
| id  | type  |
+-----+-------+
|  1  |  red  |
|  1  |  blue |
|  3  |  red  |
+-----+-------+

我们可以使用以下两种 JOIN 顺序,为表 A,B 和 C:

SELECT * FROM A
JOIN B ON A.id=B.id
JOIN C ON A.id=C.id;

结果:

+-----+-------+-------+------+-------+
| id  | name  | id    | city | type  |
+-----+-------+-------+------+-------+
|  1  | Alice |   1   |London|  red  |
|  1  | Alice |   1   |London|  blue |
+-----+-------+-------+------+-------+

我们可以看到,结果是两个 A 表中 id 为 1 的行与 C 表中 id 为 1 的两行的组合。这是由于 JOIN 的顺序不同导致的。

现在,让我们将 JOIN 顺序更改为 B,A 和 C:

SELECT * FROM B
JOIN A ON B.id=A.id
JOIN C ON A.id=C.id;

结果:

+-----+-------+-----+------+-------+
| id  | city  | id  | name | type  |
+-----+-------+-----+------+-------+
|  1  |London |  1  |Alice |  red  |
|  1  |London |  1  |Alice | blue  |
+-----+------+-----+------+-------+

现在结果只包含与 B 表的 id 匹配的两个行。这比先 JOIN A 和 B 更有效,因为我们过滤掉了必须在 A 中找到的额外行。

当我们有多个表时,选择正确的 JOIN 顺序就变得更加重要,但是需要进行试验以找到最佳方式。

避免使用 SELECT *

选择性地选择需要返回的列,而不是使用 SELECT *,可以大大减少查询的执行时间。当使用 JOIN 时特别重要,因为它可以减少传输数据的数量。

避免在 JOIN 中使用函数

当在 JOIN 条件中使用函数时,查询的执行效率会受到很大的影响。因为 MySQL 必须对表中的每一行运行函数,这会显著增加延迟时间。相反,最好在条件中使用列值,这样 MySQL 就可以使用索引快速查找。

防止使用子查询

虽然子查询可以解决确切的问题,但是它们需要额外的时间来执行,特别是当它们嵌套在 JOIN 中时。如果可能的话,最好使用 JOIN 替代子查询。

结论

通过选择正确的 JOIN 类型,定义索引,选择最佳的 JOIN 顺序,避免使用 SELECT *,避免在 JOIN 中使用函数以及避免使用子查询,我们可以改善 SQL JOIN 查询的性能并减少查询的执行时间。无论您选择哪种方法,始终记住测试和试验,以找到最优的方法和最佳的性能。

参考资料