Php 两个表之间的SQL查询效率

Php 两个表之间的SQL查询效率,php,mysql,sql,Php,Mysql,Sql,我有一个非常慢的查询(MySQL)(大约15秒)。我已经更改了列和表的名称,如果有任何类型错误,请道歉;原始查询正在运行,只保留概念,不保留文本查询 SELECT id, b, (SELECT MAX( day ) FROM all_days WHERE all_days.id = X.id ) AS day FROM X 请注意,所有_天都有超过200万行。我有3个索引:一个用于id,另一个用于day,另一个用于{id,day} 但如果我使用UNION将查询分为N个查询,则只需1秒或更短

我有一个非常慢的查询(MySQL)(大约15秒)。我已经更改了列和表的名称,如果有任何类型错误,请道歉;原始查询正在运行,只保留概念,不保留文本查询

SELECT 
id,
b, 
(SELECT MAX( day )
FROM all_days
WHERE all_days.id = X.id
) AS day
FROM X
请注意,所有_天都有超过200万行。我有3个索引:一个用于id,另一个用于day,另一个用于{id,day}

但如果我使用UNION将查询分为N个查询,则只需1秒或更短的时间即可得到相同的结果:

<?php
$ids = getIds(); // get all ID from X with a query
$i = 0
foreach ($ids as $id) {
     if ($i++ > 0) {
         $query .= " UNION ";
     }
     $query .= "SELECT MAX( day )
     FROM all_days
     WHERE all_days.id = $id";

}
?>

请尝试此查询:

SELECT 
id,
b, 
max_day
FROM X
INNER JOIN
(
  SELECT id, MAX(`day`) AS max_day
  FROM all_days
  GROUP BY id
) AS max_days
ON max_days.id = X.id

这应该快得多的原因是,这里每个id的最大值(天)存储在内存中(或磁盘上的临时表,如果太大),然后连接到表X。在查询中,您读取表X的每一行,并在所有天内查询表的每一行。

在这样的简单情况下(假设X.id/X.b的组合是唯一的),则无需子查询即可完成此操作:-

SELECT X.id,
        X.b, 
        MAX( all_days.day ) AS day
FROM X
LEFT OUTER JOIN all_days
ON all_days.id = X.id
GROUP BY X.id, X.b

您的问题不清楚-是否在
所有天.id
上都有索引?请发布您的表定义和用于完成信息的索引谢谢您的评论。我已经添加了结构。@user3796513您尝试过了吗?太好了,谢谢。我必须了解此内部联接为何如此高效(0.0006秒)vs原始子查询。@user3796513原因很简单,这里每个id的最大值(天)如果太大,则存储在内存或磁盘上的临时表中,然后连接到表X。在您的查询中,您读取了表X的每一行以及所有天中查询表的每一行。正如您所经历的那样,速度非常慢。您使用
union
的方法毫无意义,我必须说;)非常感谢您的评论。您的版本也在运行,但大约需要3秒,而@fancyPants的版本不到0.001秒。我不知道为什么会有这么大的区别。通常对于这样一个简单的查询,它会更快,因为它可以使用索引进行连接。MySQL不善于加入子查询(当子查询中只有少量记录时,这不是一个真正的问题),这可能会影响@fancyPants解决方案。由于all_days表上的覆盖索引同时覆盖id和day(按该顺序),因此应该有效地连接。使用内部联接会有所帮助,但如果X在所有天内都有不匹配的记录,这将无法解决(fancyPants解决方案无论如何都有这个问题)。你能在你的表格上运行这个查询作为解释并发布结果吗。
SELECT X.id,
        X.b, 
        MAX( all_days.day ) AS day
FROM X
LEFT OUTER JOIN all_days
ON all_days.id = X.id
GROUP BY X.id, X.b