繁体   English   中英

MySQL替代使用子查询

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM