[英]Turn a Mysql Subquery in a Join
How can I turn this subquery in a JOIN
? 如何在
JOIN
转换此子查询?
I read that subqueries are slower than JOIN
s. 我读到子查询比
JOIN
慢。
SELECT
reklamation.id,
reklamation.titel,
(
SELECT reklamation_status.status
FROM reklamation_status
WHERE reklamation_status.id_reklamation = reklamation.id
ORDER BY reklamation_status.id DESC
LIMIT 1
) as status
FROM reklamation
WHERE reklamation.aktiv=1
Using JOIN
query can be rewritten to: 使用
JOIN
查询可以重写为:
SELECT reklamation.id, reklamation.titel, reklamation_status.status
FROM reklamation
JOIN reklamation_status ON reklamation_status.id_reklamation = reklamation.id
WHERE reklamation.aktiv=1
This should do it: 这应该这样做:
SELECT r.id, r.titel, MAX(s.id) as status
FROM reklamation r
LEFT JOIN reklamation_status s ON s.id_reklamation = r.id
WHERE r.aktiv = 1
GROUP BY r.id, r.titel
The key point here is to use aggregation to manage the cardinality between reklamation
and reklamation_status
. 这里的关键点是使用聚合来管理
reklamation
和reklamation_status
之间的基数。 In your original code, the inline subquery uses ORDER BY reklamation_status.id DESC LIMIT 1
to return the highest id
in reklamation_status
that corresponds to the current reklamation
. 在原始代码中,内联子查询使用
ORDER BY reklamation_status.id DESC LIMIT 1
返回reklamation_status
中与当前reklamation
对应的最高id
。 Without aggregation, we would probably get multiple records in the resultset for each reklamation
(one for each corresponding reklamation_status
). 如果没有聚合,我们可能会在结果
reklamation
为每个reklamation
获取多个记录(每个对应的reklamation_status
)。
Another thing is to consider is the type of the JOIN
. 另一件事是考虑是
JOIN
的类型。 INNER JOIN
would filter out records of reklamation
s that do not have a reklamation_status
: the original query with the inline subquery does not behave like that, so I chose LEFT JOIN
. INNER JOIN
会过滤掉的记录reklamation
没有A S reklamation_status
:与内联子查询的原始查询不那样做,所以我选择了LEFT JOIN
。 If you can guarantee that every reklamation
has at least one child in reklamation_status
, you can safely switch back to INNER JOIN
(which might perform more efficiently). 如果您可以保证每个
reklamation
在reklamation
中至少有一个子reklamation_status
,则可以安全地切换回INNER JOIN
(可能更有效地执行)。
PS: PS:
I read that subqueries are slower than
JOIN
s.我读到子查询比
JOIN
慢。
This is not a universal truth. 这不是一个普遍的事实。 It depends on many factors and cannot be told without seeing your exact use case.
这取决于很多因素,如果没有看到确切的用例,就无法告知。
What you read is incorrect. 你读的是不正确的。 Subqueries can be slower, faster, or the same as joins.
子查询可以更慢,更快或与联接相同。 I would write the query as:
我会把查询写成:
SELECT r.id, r.titel,
(SELECT rs.status
FROM reklamation_status rs
WHERE rs.id_reklamation = r.id
ORDER BY rs.id DESC
LIMIT 1
) as status
FROM reklamation r
WHERE r.aktiv = 1;
For performance, you want an index on reklamation_status(id_reklamation, id, status)
. 为了提高性能,您需要
reklamation_status(id_reklamation, id, status)
的索引。
By the way, this is a case where the subquery is probably the fastest method for expressing this query. 顺便说一下,这是子查询可能是表达此查询的最快方法的情况。 If you attempt a
JOIN
, then you need some sort of aggregation to get the most recent status. 如果您尝试
JOIN
,则需要某种聚合来获取最新状态。 That can be expensive. 这可能很昂贵。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.