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
差。