Mysql 避免从同一个表中添加新列(info)的多个内部联接

Mysql 避免从同一个表中添加新列(info)的多个内部联接,mysql,sql,select,join,Mysql,Sql,Select,Join,我想知道是否有一种方法可以从中的架构中为用户id、发件人用户id和收件人用户id带来信息 我现在唯一能想到的方法就是进行嵌套的内部联接,我觉得这样效率很低: SELECT e.id ,msg_owner ,msg_owner_name ,sender_user_id ,sender_name ,recipient_user_id ,f.NAME AS recipient_name ,msg_body ,created_at FROM

我想知道是否有一种方法可以从中的架构中为
用户id
发件人用户id
收件人用户id
带来
信息

我现在唯一能想到的方法就是进行嵌套的内部联接,我觉得这样效率很低:

SELECT e.id
    ,msg_owner
    ,msg_owner_name
    ,sender_user_id
    ,sender_name
    ,recipient_user_id
    ,f.NAME AS recipient_name
    ,msg_body
    ,created_at
FROM (
    SELECT c.id
        ,msg_owner
        ,msg_owner_name
        ,sender_user_id
        ,d.NAME AS sender_name
        ,recipient_user_id
        ,msg_body
        ,created_at
    FROM (
        SELECT a.id
            ,user_id AS msg_owner
            ,NAME AS msg_owner_name
            ,sender_user_id
            ,recipient_user_id
            ,msg_body
            ,created_at
        FROM messages AS a
        INNER JOIN users AS b ON a.user_id = b.id
        ) AS c
    INNER JOIN users AS d ON c.sender_user_id = d.id
    ) AS e
INNER JOIN users AS f ON e.recipient_user_id = f.id

是否有任何(更有效的)方法为上述三列中的每一列输入
name
值?感谢您的回答/建议

在同一个查询上可以有多个
join
子句,而无需嵌套。我不确定这是否会提高性能,但至少会使查询变得不那么麻烦:

SELECT m.id,
       m.user_id AS msg_owner,
       o.name AS msg_owner_name,
       m.sender_user_id,
       s.name,
       m.recipient_user_id,
       r.name AS recipient_name,
       m.body,
       m.created_at
FROM   messages m
JOIN   users o ON m.user_id = o.id
JOIN   users s ON m.sender_user_id = s.id
JOIN   users r ON m.recipient_user_id = r.id

只使用联接,而不是嵌套联接

按照您的方式,强制数据库收集每个内部查询的所有结果,然后将其连接到另一个表。除非通过WHERE子句对最内部查询的内容进行非常有限的限制,否则这对性能总是不利的

下面是使用联接的正确方法。它允许直接使用索引(如果存在的话)来加快速度

SELECT m.id
    ,owner.id AS msg_owner
    ,owner.name AS msg_owner_name
    ,m.sender_user_id
    ,sender.name AS sender_name
    ,m.recipient_user_id
    ,recipient.name AS recipient_name
    ,m.body AS msg_body
    ,m.created_at
FROM messages m
INNER JOIN users sender
ON sender.id = m.sender_user_id
INNER JOIN users recipient
ON recipient.id = m.recipient_user_id
INNER JOIN users owner
ON owner.id = m.user_id

您的多个内部联接没有问题。这是完全正常和正确的。我唯一要做的更改是,您不需要三个嵌套选择
从a.a=b.x上的内部联接b中选择a.id、b.id、c.id a.b=c.y上的内部联接c
工作正常……在给定示例输入表的情况下,您能否发布一个表,列出您希望结果是什么样的?由于您没有嵌套的聚合组,因此整个过程很可能在没有任何嵌套选择的情况下完成,而是使用同一级别的所有联接。@MatBailie感谢您的建议@MichaelBerkowski Mike,我以为SQLFIDLE会保存我的示例(所需)表,但它没有。但从我问题中的查询可以看出,我试图将[users]表中的“name”信息带到三个不同的列中。谢谢你的帮助!比我快几秒钟。@Mureinik谢谢你回答我的问题!我现在知道可以使用许多这样的
内部连接。我接受了Willem的回答,因为他对性能做了更多的解释,并认为这可能对像我这样的SQL初学者有用。:)谢谢你的回答和详细的解释。Mureinik的答案也是我一直在寻找的,但我认为你的答案是“正确的”,因为它提供的信息稍微多一些。谢谢大家!@有一天,在SQLFiddle中比较每个查询的
EXPLAIN
计划时,您可以看到不同之处。但是,您是正确的,它不一定首先查询最里面的行。在我所经历的每一种情况下,当有人创建类似OP的查询时,它的性能都比直接连接要差得多。另见。稍后我会更新我的答案(工作电话),详细说明OP解释计划中的
ref
ALL
如何意味着性能比我查询的解释计划中的
eq\u ref
差。