十二 28 2009

用例子说明inner join,left join,right join,full join的区别

Published by 笨二十一 at 3:54 下午 under MySQL,Web技术

最近论坛的数据超过了1600万了,时不时的出现访问速度超慢的情况,虽然不是出现频率很多,但也很影响论坛的正常运行。今天终于抽出一些时间来优化一下,经过分析,发现主要是在一个更新主贴回帖数的语句上出现了问题,因为我们的论坛是从dvbbs转过来的,所以当时这个语句做过调整,原来的语句是

SELECT count(*) FROM cdb_posts AS p LEFT JOIN cdb_members AS m ON p.authorid = m.uid WHERE p.tid = '1213675' AND p.invisible = '0' AND p.fid NOT IN (444,92) AND m.uid IS NOT NULL

发现效率真的很差,经常要执行10秒左右,于是现学现卖,抓紧学知识,首先是加索引,效果不错问题解决了。但是我还是想优化一下这个语句。因为这里面的left join一直以来概念模糊,只知道人家用我也用。今天到网上仔细找了找资料学习了一番,把这个语句改成了

SELECT count(*) FROM cdb_posts AS p INNER JOIN cdb_members AS m ON p.authorid = m.uid WHERE p.tid = '1213675' AND p.invisible = '0' AND p.fid NOT IN (444,92)

下面总结一下inner join,left join,right join,full join的区别

[TEST@ORA1] SQL>select * from a;

编号 姓名
—- ———-
1000 张三
2000 李四
3000 王五

[TEST@ORA1] SQL>select * from b;

编号 商品
—- ———-
1000 电视机
2000 录像机
4000 自行车

[TEST@ORA1] SQL>set null 空值–这里为了显示方面我把NULL定义成了[空值]

[TEST@ORA1] SQL>select a.*,b.* from a inner join b on a.编号=b.编号;

编号 姓名       编号 商品
—- ———- —- ———-
1000 张三       1000 电视机
2000 李四       2000 录像机

[TEST@ORA1] SQL>select a.*,b.* from a left join b on a.编号=b.编号;

编号 姓名       编号 商品
—- ———- —- ———-
1000 张三       1000 电视机
2000 李四       2000 录像机
3000 王五       空值 空值

[TEST@ORA1] SQL>select a.*,b.* from a right join b on a.编号=b.编号;

编号 姓名       编号 商品
—- ———- —- ———-
1000 张三       1000 电视机
2000 李四       2000 录像机
空值 空值       4000 自行车

[TEST@ORA1] SQL>select a.*,b.* from a full join b on a.编号=b.编号;

编号 姓名       编号 商品
—- ———- —- ———-
1000 张三       1000 电视机
2000 李四       2000 录像机
3000 王五       空值 空值
空值 空值       4000 自行车

================================

看例子就一目了然啦。

No responses yet

Trackback URI | Comments RSS

Leave a Reply

You must be logged in to post a comment.