[英]MySQL alternative to using a subquery
假设我有下表“人员和工资”。 这是1-N关系,一个人可以拿到不止一个工资。
**Person**
id
name
**Wage**
id
person_id
amount
effective_date
现在,我想查询所有人员及其最新工资的列表。 我可以通过执行以下查询来获得结果:
SELECT
p.*,
( SELECT w.amount
FROM wages a w
WHERE w.person_id = p.id
ORDER BY w.effective_date
LIMIT 1
) as wage_amount,
( SELECT w.effective_date
FROM wages a w
WHERE w.person_id = p.id
ORDER BY w.effective_date
LIMIT 1
) as effective_date
FROM person as p
问题是,我的查询将具有来自不同表的多个子查询。 我想使其尽可能高效。 除了使用子查询之外,还有没有其他选择可以更快地产生相同的结果?
子查询可以是一个很好的解决方案,就像Sam S在回答中提到的那样,但这实际上取决于子查询,您使用的dbms和索引。 请参阅以下问题和答案,以更好地讨论子查询与联接的性能: 联接与子查询
如果性能是您的问题,则必须考虑使用dbms的EXPLAIN
命令。 它将向您显示查询的构建方式以及瓶颈所在。 根据其结果,您可以考虑以其他方式重写查询。
例如,通常情况下, join
会产生更好的性能,因此您可以根据以下答案重写查询: https : //stackoverflow.com/a/2111420/362298并比较它们的性能。
请注意,创建正确的索引也会有很大的不同。
希望能帮助到你。
正确的索引编制可能会使您的版本有效地工作(即, wages(person_id, effective_date)
的索引wages(person_id, effective_date)
)。
以下通过单个子查询产生相同的结果:
SELECT p.*, w.amount, w.effective_date
from person p left outer join
(select person_id, max(effective_date) as maxdate
from wages
group by personid
) maxw
on maxw.person_id = p.id left outer join
wages w
on w.person_id = p.id and w.effective_date = maxw.maxdate;
这个版本可能比上面的版本更好地使用索引:
SELECT p.*, w.amount, w.effective_date
from person p left outer join
wages w
on w.person_id = p.id
where not exists (select * from wages w2 where w2.effective_date > w.effective_date);
请注意,当有两个具有相同最大有效日期的“工资”时,这些版本将为一个人返回多行。
只要确保使用索引,子查询就会非常有效。 尝试对查询运行EXPLAIN ,看看它是否使用正确的索引
从人员p左联接中选择工资名称,w.amount,MAX(w。生效日期)的最大值w.person_id = p.id GROUP BY p.name
我没有测试此查询。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.