所以...哪一个更快(NULl值不是问题),并被索引。
SELECT * FROM A
JOIN B b ON b.id = a.id
JOIN C c ON c.id = b.id
WHERE A.id = '12345'
使用左连接:
SELECT * FROM A
LEFT JOIN B ON B.id=A.bid
LEFT JOIN C ON C.id=B.cid
WHERE A.id = '12345'
这是实际查询 这里..都返回相同的结果
Query (0.2693sec) :
EXPLAIN EXTENDED SELECT *
FROM friend_events, zcms_users, user_events,
EVENTS WHERE friend_events.userid = '13006'
AND friend_events.state =0
AND UNIX_TIMESTAMP( friend_events.t ) >=1258923485
AND friend_events.xid = user_events.id
AND user_events.eid = events.eid
AND events.active =1
AND zcms_users.id = user_events.userid
EXPLAIN
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE zcms_users ALL PRIMARY NULL NULL NULL 43082
1 SIMPLE user_events ref PRIMARY,eid,userid userid 4 zcms_users.id 1
1 SIMPLE events eq_ref PRIMARY,active PRIMARY4 user_events.eid 1 Using where
1 SIMPLE friend_events eq_ref PRIMARY PRIMARY 8 user_events.id,const 1 Using where
LEFTJOIN QUERY: (0.0393 sec)
EXPLAIN EXTENDED SELECT *
FROM `friend_events`
LEFT JOIN `user_events` ON user_events.id = friend_events.xid
LEFT JOIN `events` ON user_events.eid = events.eid
LEFT JOIN `zcms_users` ON user_events.userid = zcms_users.id
WHERE (
events.active =1
)
AND (
friend_events.userid = '13006'
)
AND (
friend_events.state =0
)
AND (
UNIX_TIMESTAMP( friend_events.t ) >=1258923485
)
EXPLAIN
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE friend_events ALL PRIMARY NULL NULL NULL 53113 Using where
1 SIMPLE user_events eq_ref PRIMARY,eid PRIMARY 4 friend_events.xid 1 Using where
1 SIMPLE zcms_users eq_ref PRIMARY PRIMARY 4 user_events.userid 1
1 SIMPLE events eq_ref PRIMARY,active PRIMARY 4 user_events.eid 1 Using where
答案 0 :(得分:9)
取决于;跑他们两个找出来;然后运行'解释选择'以获得解释。
实际的性能差异可能从“几乎不存在”到“非常重要”,具体取决于A中id ='12345'的行数在B和C中没有匹配记录。
更新(基于发布的查询计划)
当你使用INNER JOIN时,哪个表开始时无关紧要(结果方面,而不是性能方面),因此优化器会尝试选择它认为最佳的表。您似乎在所有适当的PK / FK列上都有索引,并且您在friend_events.userid
上没有索引,或者userid = '13006'
的记录太多而且没有被使用;无论哪种方式优化器选择具有较少行的表作为“基础” - 在这种情况下它是zcms_users
。
当你使用LEFT JOIN时,确实重要(结果明智)从哪个表开始;因此选择了friend_events
。现在为什么它花费的时间更少,我不太确定;我猜friend_events.userid
条件有帮助。如果要在其上添加一个索引(实际上是varchar,btw?不是数字?),你的INNER JOIN也可能表现不同(也变得更快)。
答案 1 :(得分:4)
INNER JOIN必须进行额外的检查以从A中删除任何在B和C中没有匹配记录的记录。根据最初从A返回的记录数量,它可能会产生影响。
答案 2 :(得分:2)
使用EXPLAIN查看查询计划。对于这两种情况,它可能是相同的计划,所以我怀疑它有很大的不同,假设没有不匹配的行。但这些是两个不同的查询,所以比较它们真的没有意义 - 你应该使用正确的查询。
为什么不使用“INNER JOIN”关键字而不是“LEFT JOIN”?
答案 3 :(得分:1)
LEFT JOIN
显示来自A
的所有数据,仅在条件为真时才显示来自B/C
的数据。对于INNER JOIN
,它必须对tables
进行额外检查。所以,我想这可以解释为什么LEFT JOIN
更快。