在联接中打开Mysql子查询

在联接中打开Mysql子查询,mysql,sql,Mysql,Sql,如何在联接中打开此子查询 我读到子查询比JOINs慢 SELECT reklamation.id, reklamation.titel, ( SELECT reklamation_status.status FROM reklamation_status WHERE reklamation_status.id_reklamation = reklamation.id ORDER BY reklam

如何在
联接中打开此子查询

我读到子查询比
JOIN
s慢

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

使用
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
这应该做到:

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
这里的关键点是使用聚合来管理
reklamation
reklamation\u status
之间的基数。在原始代码中,内联子查询使用
ORDER BY reklamation_status.id DESC LIMIT 1
返回
reklamation_status
中与当前
reklamation
相对应的最高
id
。如果没有聚合,我们可能会在resultset中为每个
reklamation
(每个对应的
reklamation\u状态
)获得多条记录

另一件事是考虑< <代码>连接> /代码>的类型。代码>内部联接

将过滤掉
重新命名
中没有
重新命名状态的记录
:带有内联子查询的原始查询的行为与此不同,因此我选择了
左联接
。如果您可以保证每个
更新
至少有一个子项处于
更新状态
,则可以安全地切换回
内部连接
(这可能会执行得更有效)


附言:

我读到子查询比
JOIN
s慢

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

这不是一个普遍的真理。它取决于许多因素,如果没有看到您的确切用例,就无法判断。

您所阅读的内容是不正确的。子查询可以更慢、更快,或者与连接相同。我将把查询写为:

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;
为了提高性能,您需要在
reklamation\u status(id\u reklamation,id,status)
上建立索引

顺便说一下,在这种情况下,子查询可能是表示此查询的最快方法。如果尝试加入,则需要某种聚合来获取最新状态。那可能很贵