带有内部连接的 MySQL 查询非常慢

标签 mysql sql database join

我有两个表,每个表包含 600 万行。我正在尝试使用内部联接来加入两者,但查询运行了 2 天而没有完成。连接是(注意我使用 count(*) 只是为了让我能够运行解释,我实际上是在 CTAS 中使用 join):

SELECT count(*)
FROM table1 t1,
     table2 t2
WHERE t1.col1 = t2.colA
  AND t1.col2 = t2.colB;

经过一些调查,我发现下面的查询运行良好:

SELECT count(*)
FROM
  (SELECT *
   FROM table1) t1,

  (SELECT *
   FROM table2) t2
WHERE t1.col1 = t2.colA
  AND t1.col2 = t2.colB;

唯一的区别是我使用子查询SELECT * FROM table;

运行解释计划显示后一个查询在选择 table2 时正在建立索引。而第一个查询使用的是连接缓冲区( block 嵌套循环)。

MySQL 肯定足够聪明,可以计算出这两个查询实际上是相同的,并且对两个查询执行相同的操作?我不明白为什么需要索引,因为无论如何都需要对两个表进行全面扫描。这些是临时/临时表,所以如果我确实在上面放置了索引,它实际上只是为了执行此连接。

有没有办法通过 MySQL 配置来解决这个问题?

最佳答案

您至少需要一个表的索引,即使是

create index Temp1 on Table2 ( colA, colB )

因此,您从表 1 中的查询连接到表 2,所以即使表扫描是在所有表 1 上,您也需要它来快速找到表 2 中匹配的记录。如果 NEITHER 没有索引,然后这样想。对于表 1 中的每条记录,扫描表 2 中的所有记录并获取与 ColA、ColB 匹配的所有记录。现在,返回表 1 获取第二条记录...返回表 2 获取所有记录,直到找到匹配项。

由于您有 6M 条记录,您几乎可以在性能上扼杀一头母牛(可以这么说)。通过索引,即使在 SECOND 表上,当查询在第一条记录上时,它可以立即跳转到与 ColA、ColB 匹配的行,并且一旦这些 A/B 记录完成,它就会返回到第一条表。

现在,对于其他开销效率。如果您在各自的 Col1、Col2 和 ColA、ColB 上索引了两个表,那么引擎将在其内存中/缓存每个公共(public)区域的整个记录​​ block ,并且不必继续返回原始数据页其他元素重复。

因此,即使您认为它可能不实用,但处理大型表查询仍然很好。此外,如果第一个表中的多个记录具有相同的 Col1、Col2 值,但表中其他列的其他值不同,并且类似地在多个 ColA、ColB 的第二个表中,您将得到笛卡尔结果.考虑以下场景

Table1
Col1  Col2  OtherColumn
X     Y     blah1
X     Y     blah2
X     Y     blah3


Table2
ColA  ColB  OtherColumn
X     Y     second blah1
X     Y     second blah2
X     Y     second blah3

像你这样的简单查询

SELECT count(*)
FROM table1 t1,
     table2 t2
WHERE t1.col1 = t2.colA
  AND t1.col2 = t2.colB;

将导致计数为 9。您有 6M 条记录和可能的笛卡尔结果?希望这可以澄清您可能遇到的一些问题。

关于带有内部连接的 MySQL 查询非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35067788/

相关文章:

Android MySQL 仅在 Android 4.0 中存在问题?

mysql - 是否可以从另一个 View 创建 View ?

c# - 如何将 SQL 异常抛回给调用的 asp.net 应用程序?

c# - Entity Framework 查询得到改进

mysql - 在第一个表的字段或第二个表的字段中使用 WHERE 进行左连接

mysql - 嵌套数据使用什么表结构?

mysql - 为什么这个 group_concat 不起作用?

mysql - 在迁移或 Eloquent 模型中设置默认值?

java - 使用参数从 JPQL 查询中选择全部

database - 如何从 Hasura 数据库将数据导出为 CSV 文件?