我在这个网站上搜索了许多类似的回复,并在此过程中分几个阶段改进了我的代码。不幸的是,这个 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/