mysql - 跨多个表优化 INNER JOIN

标签 mysql sql

我在这个网站上搜索了许多类似的回复,并在此过程中分几个阶段改进了我的代码。不幸的是,这个 3 行查询仍然无法运行。

我有一个包含 10 万多行和大约 30 列的表,我可以将其中过滤到 3 行(在本示例中),然后在 21 个小型查找表中执行INNER JOIN

在我的第一次尝试中,我很懒并且使用了隐式连接。

SELECT `master_table`.*, `lookup_table`.`data_point` x 21
FROM `lookup_table` x 21
WHERE `master_table`.`indexed_col` = "value"
AND `lookup_table`.`id` = `lookup_col` x 21

查询看起来超时:

#2013 - 查询期间失去与 MySQL 服务器的连接

在此之后,我尝试明确连接。

SELECT `master_table`.*, `lookup_table`.`data_point` x 21
FROM `master_table`
INNER JOIN `lookup_table` ON `lookup_table`.`id` = `master_table`.`lookup_col` x 21
WHERE `master_table`.`indexed_col` = "value"

仍然得到相同的结果。然后我意识到查询可能首先尝试执行联接,然后通过 WHERE 子句进行过滤。因此,经过更多研究后,我了解了如何应用子查询首先执行过滤器,然后对新创建的表执行联接。这就是我到达的地方,它仍然返回相同的错误。有什么方法可以进一步改进这个查询吗?

SELECT `temp_table`.*, `lookup_table`.`data_point` x 21
FROM (SELECT * FROM `master_table` WHERE `indexed_col` = "value") as `temp_table`
INNER JOIN `lookup_table` ON `lookup_table`.`id` = `temp_table`.`lookup_col` x 21

这是编写此类查询的最佳方式吗?我测试了子查询以确保它只返回一个小表,并且可以确认它只返回三行。

最佳答案

首先,从您正在寻找的最简单的方面来看

select
      mt.*
   from
      Master_Table mt
   where
      mt.indexed_col = 'value'

如果您在主表上的第一个位置给定的 indexed_col 上有一个索引(如果您有许多字段的复合索引),那么这可能是瞬时的...

现在,如果我正确理解了您对不同查找列(总共 21 个)的理解,那么您只是在这篇文章中简化了它们以实现冗余,但实际上做了一些效果

select
      mt.*,
      lt1.lookupDescription1,
      lt2.lookupDescription2,
      ...
      lt21.lookupDescription21
   from
      Master_Table mt
         JOIN Lookup_Table1 lt1
            on mt.lookup_col1 = lt1.pk_col1
         JOIN Lookup_Table2 lt2
            on mt.lookup_col2 = lt2.pk_col2
         ...
         JOIN Lookup_Table21 lt21
            on mt.lookup_col21 = lt21.pk_col21
   where
      mt.indexed_col = 'value'

十多年前,我有一个项目处理类似的情况...主表有大约 21 多万条记录,必须连接到大约 30 多个查找表。系统爬行和查询在运行查询超过 24 小时后死亡。

这也是在 MySQL 服务器上,修复是单个 MySQL 关键字...

Select STRAIGHT_JOIN mt.*, ...

通过将主表放在主要位置,将 where 子句及其条件直接放在主表上,就可以了。您知道表的关系。按照我向您提供的确切顺序进行查询。不要试图为我思考这一点,并尝试基于可能具有较小记录数的子表进行优化,并以某种方式认为这将有助于更快地查询......它不会。

尝试使用 STRAIGHT_JOIN 关键字。它完成了我正在处理的查询并在大约 1.5 小时内完成...它返回了所有 2100 万行以及最终输出的所有相应查找键描述,因此仍然需要比 3 条记录更长的持续时间。

关于mysql - 跨多个表优化 INNER JOIN,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56283287/

相关文章:

mysql - 填补 Mysql 中数据范围之间的空白

sql - 增加 "select top"返回的行突然使查询变得非常慢

java - 从两个不同的表插入一个表并具有自动增量值

sql - 从事件流中 self 加入日期的有效方法是什么?

java - Hibernate:没有 SQL 字符串的查询?

PHP MySQL 数据库类不适用于插入

php - 如何建立重叠的基于时间的定价系统

mysql - 尝试在 SSRS 报告中选择特定列

php - MySQL/PHP - 时间流逝

php - mysql 避免sql注入(inject)