开始编辑时间:2016-06-17 19:16:57
先交代下背景
最近进行了一个小模块的开发,由于几个数据表之间的联动比较多,所以外链接次数也有几次。
但是公司本来就是禁止随便使用外链接语句的,但是不用外链接的话达不到想要的效果(自己经验不够,想不到别的解决办法)。
期间在网上搜索了一下有什么别的解决办法,但是效果都没有达到预期,而且看到也有人问过类似的问题,而且有很多人不理解为什么不用能外链接,还有的人说,不用外链接还用什么关系数据库。
后来请教了上司,得出结果是外链接可以用,不过要小心注意。
下面说说自己在项目中的实战理解:
首先,看下面的SQL语句:
SELECT * FROM articles a LEFT JOIN comments c ON a.id=c.articles_id LEFT JOIN users u ON a.user_id = u.id;
首先自己分析了一下这个表在数据库到底做了什么动作:
-
- 首先a表全表查询了一次,这个应该毫无疑问;
- 为了找出每一条符合连接条件的记录,首先遍历每一条a表的每一条记录,在每一次的循环中,都需要对c表和u表进行全表查询查询,并且检查是否符合条件,如果符合条件则添加到结果表对应的记录后面
那么现在假设a表有50条数据,c表有20条,u表10条。
那么最少就进行了50*20+50*10=1500次的全表查询。(这种数据量可能还感觉不到什么)
但是如果当表中的数量再翻100倍,操作量变成1500万次。
如果再把SQL语句改一下:
SELECT * FROM articles a LEFT JOIN comments c ON a.id=c.articles_id LEFT JOIN users u ON c.user_id = u.id;
操作就会变成a表全表查询1次,然后每一条记录全表查询c表一次,然后c表每一条记录又会全表查询u表一次。
操作量模型就会变成:50*20*10=10000次,数据量翻100倍,操作量变成100亿次....
然后我们可以考虑一下并发的问题....
其实在现实中一些公司的某些的特定数据表达到更高的数据量是肯定的,如果不注意使用这类连接语句,一个并发服务器就死掉也并不是不可能。
那么下面说说暂时解决方案(例子):
SELECT * FROM articles a limit 0,10LEFT JOIN comments c ON a.id=c.articles_idLEFT JOIN users u ON c.user_id = u.id;
这里先对a表做一个分页,那么整个模型一下子少了对于上面a表5000条数据,c表2000条数据量,u表1000条数据量的操作,模型就会变成10*2000*1000=2000万次。
在实际应用中,我还对中间表(c表的位置)添加了条件:
...LEFT JOIN (Select * from comment where ....) c on a.id=c.articles_id....
编辑结束时间:2016-06-17 20:23:50