繁体   English   中英

左JOIN更快或内连接更快?

[英]Left JOIN faster or Inner Join faster?

那么......哪一个更快(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

这取决于; 跑他们两个找出来; 然后运行'解释选择'来解释。

实际性能差异的范围可以从“几乎不存在”到“非常重要”,具体取决于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也可能表现不同(并且变得更快)。

INNER JOIN必须进行额外的检查以从A中删除任何在B和C中没有匹配记录的记录。根据最初从A返回的记录数量,它可能会产生影响。

使用EXPLAIN查看查询计划。 对于这两种情况,它可能是相同的计划,所以我怀疑它有很大的不同,假设没有不匹配的行。 但这些是两个不同的查询,所以比较它们真的没有意义 - 你应该使用正确的查询。

为什么不使用“INNER JOIN”关键字而不是“LEFT JOIN”?

LEFT JOIN显示来自A所有数据,仅在条件为真时才显示来自B/C数据。 对于INNER JOIN ,它必须对两个tables进行一些额外的检查。 所以,我想这可以解释为什么LEFT JOIN更快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM