首页 > 解决方案 > MySQL:在 JOIN 中扫描了多少表行?

问题描述

JOIN如果我有三个表,每个表有 1000 行,编号从 1 到 1000,那么 MySQL 在以下s 查询期间进行了多少比较:

SELECT *
FROM table_1 t1 
JOIN table_2 t2 ON t1.id_1 = t2.id_2
JOIN table_3 t3 ON t2.id_2 = t3.id_3;

SELECT *
FROM table_1 t1 
JOIN table_2 t2 
JOIN table_3 t3
WHERE t1.id_1 = t2.id_2 AND t2.id_2 = t3.id_3;

请注意,任何表上都没有索引。这两个查询有区别吗?我在想,在第二个查询中,它的目的是让 MySQL 创建所有三个表的笛卡尔积,然后过滤掉匹配条件的行(必须扫描 1000 X 1000 X 1000 行)但在内部它被转换为第一个查询,它将在第一个 JOIN 中扫描 1000 X 1000 行,然后在第二个 JOIN 中扫描另外 1000 X 1000 行。结果应该是相同的(1000 行三列具有相同的数字 1 到 1000)。

哪一个?1000 X 1000 X 1000 行或 1000 X 1000 + 1000 X 1000 行

阅读 Paul DuBois 的 MySQL 的“查询优化”一章(第 4 版,第 306 页)后出现的问题:

在此处输入图像描述

标签: mysqljoinoptimization

解决方案


这两个查询的处理方式相同。

清楚起见ON应说明表格之间的关系;WHERE应该过滤。

但是,对于优化,这些对于JOIN.

对于LEFT JOIN,你把条件放在哪里很重要

作为您的问题的额外皱纹,...如果表的行数不同,优化器可能会从最小的表开始。

请参阅此以了解如何计算行数:http: //mysql.rjweb.org/doc.php/index_cookbook_mysql#handler_counts

请提供SHOW CREATE TABLE以便我们理解id_1等。

在没有索引的情况下运行这样的代码是愚蠢的。

什么是预期的输出?像这样的东西?

+---+---+---+
| n | n | n |
+---+---+---+
| 0 | 0 | 0 |
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
| 4 | 4 | 4 |
| 5 | 5 | 5 |
...

推荐阅读