SELECT * FROM foo f
INNER JOIN (
SELECT bar_id, MAX(revision_id) FROM bar b
GROUP BY bar_id
) t ON t.bar_id = f.bar_id
好的,所以听到这个问题:让我们说这些表中有数百万条记录,我希望查询尽可能高效。
MySQL是否会拉出条形表的所有记录,然后在连接级别的ON语句中而不是在子查询中过滤它们?或者有没有办法在JOIN过滤器之前用SQL本身过滤子查询中的项目?
似乎查询过滤掉它们的所有记录都效率低下,我还没有想过要解决这个问题的方法。
我试过这个,但子查询无法看到foo表:
SELECT * FROM foo f
INNER JOIN (
SELECT bar_id, MAX(revision_id) FROM bar b
WHERE b.bar_id = f.bar_id
GROUP BY bar_id
) t ON t.bar_id = f.bar_id
有没有办法将id传递给子查询,我只想以最佳方式做事,我确信有办法做到这一点。
感谢所有回复。
答案 0 :(得分:0)
MySQL是否会拉出条形表的所有记录,然后在连接级别的
ON
语句中而不是在子查询中过滤它们?
最有可能的是,它会在进行连接之前完整地执行子查询。如果您想确切知道,请查看执行计划,EXPLAIN
显示它。
有一种特殊情况,这种方法甚至可能是有益的:如果bar
很大但bar_id
只需要很少的值,而foo
的很多行都会引用这几个{ {1}}值,然后在将每个id连接到bar_id
行之前选择每个id的最大修订版可能会很好。
或者有没有办法在
foo
过滤器之前只使用SQL过滤子查询中的项目?
您可以完全避免使用子查询:
JOIN
我假设SELECT f.*, MAX(b.revison_id)
FROM foo f INNER JOIN bar b ON b.bar_id = f.bar_id
GROUP BY f.foo_id
中的每一行都可以由foo
唯一标识;您可能必须在那里使用多个列,或引入新密钥。因此,结果将在foo_id
中的每一行中包含一行,但前提是foo
中至少还有一个匹配的行。 bar
中的所有行都将在bar
调用中汇总,因此您可以从这些行中获得最大MAX
。
我试过这个,但是子查询无法看到foo表:[...]
这不好用。 将工作的关闭事物将是一些依赖查询,其必须重复执行,每个foo行一次。哪个是性能杀手。如果有疑问,请尝试使用您的实际数据并简单地比较执行时间,以便进行足够多的执行。
结论:尽量避免使用subquerys,并尽量避免使用依赖子查询。