我已经在此站点上抓取了许多类似的回复,并在此过程中的多个阶段改进了我的代码。不幸的是,此三行查询仍然无法运行。
我有一个具有100k +行和大约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 - Lost connection to MySQL server during query
在此之后,我尝试对联接进行显式显示。
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
这是编写这种查询的最佳方法吗?我测试了子查询,以确保它只返回一个小表,并且可以确认它仅返回三行。
答案 0 :(得分:2)
首先,您正在寻找最简单的方面
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条记录更长的持续时间。
答案 1 :(得分:0)
首先,不要使用子查询。将查询写为:
SELECT mt.*, lt.`data_point`
FROM `master_table` mt INNER JOIN
`lookup_table` l
ON l.`id` = mt.`lookup_col`
WHERE mt.`indexed_col` = value;
所需的索引是master_table(value, lookup_col)
和lookup_table(id, data_point)
。
如果仍然存在性能问题,则有多种可能性。其中最重要的一点是结果集太大而无法在合理的时间内返回。要查看是否是这种情况,可以使用select count(*)
来计算返回的行数。