数据库优化(二) SQL优化之SELECT优化 JOIN和LEFT JOIN 和 RIGHT JOIN
在数据库的应用中,我们经常需要对多表进行连表操作来获得关系型的数据,因此,应该更加的掌握好Middleware and libraries for WSGI — WSGI.org
SQL语句的join原理,因为,可以稍一不慎,可能一个不好的join导致数据库的全表扫描,查询出大量的
无用的信息,并且对数据库性能影响极大。
数据库中的join操作,实际上是对一个表和另一个表的关联,而很多错误的理解为,先把这两个表来一个
迪卡尔积,然后扔到内存,用where和having条件来慢慢筛选,其实数据库没那么笨的,那样会占用大量的内
存,而且效率不高,比如,我们只需要的一个表的一些行和另一个表的一些行,如果全表都做迪卡尔积,这开
销也太大了,真正的做发是,根据在每一个表上的条件,边遍历一个表的同时,遍历其他表,找到满足最后的
条件后,就发送到客户端,直到最后的数据全部查完,叫做嵌套循环查询。
1,LEFT JOIN 和 RIGHT JOIN优化
在MySQL中,实现如 A LEFT JOIN B join_condition 如下:
1,表B依赖赖与表A及所有A依赖的表
2,表A依赖于所有的表,除了LEFT JOIN 的表(B)
3,join_condition决定了怎样来读取表B,where条件对B是没有用的
4,标准的where会和LEFT JOIN联合优化
5,如果在A中的一行满足where和having条件,B中没有,会被填充null
RIGHT JOIN 与LEFT JOIN类似,这个位置是可以互换的
2.1、LEFT JOIN 与 正常JOIN之间的转换原则:当where条件,对于生成的null行总返回false时,可以直接转化为
正常的join
如:
SELECT * FROM t1 LEFT JOIN t2 ON (column1) WHERE t2.column2=5;将被转换为:
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;注:因为设置了条件t2.column2 = 5,那么对于所有的生成的t2为null的行都是不成立的
这样的优化将非常快速,因为这样相当于把外连接转换为等值连接,少了很多行
的扫描和判断。
2.2嵌套循环JOIN算法----Nested-Loop Join
简单的嵌套循环算法就是从一个表开始,通过对表的条件找到一行,然后找下一个表
的数据,找完后,又回到第一个表来寻找满足条件的行
例如,有三个表t1, t2, t3,他们的join类型为:
Table Join Typet1 ranget2 reft3 ALL即,t1表通过范围扫描,t2关联t1,t3为全表扫描
这三个表的伪代码为:
for each row in t1 matching range { for each row in t2 matching reference key { for each row in t3 { if row satisfies join conditions, send to client } }}注:意思是:先根据对t1表的条件范围找到一行,和t2匹配,然后寻找t3的满足条件的行
如此循环迭代,最终找到全部满足条件的行。
2.3块嵌套循环JOIN算法 ---- Block Nested-Loop Join
这个算法的应用为:由于之前的嵌套算法每读一个表的一行后,就会读下表,这样
内部的表会被读很多次,所以,数据库利用了join缓存(join buffer)来存储中间的结
果,然后读取内部表的时候,找到一行,都和这个缓存中的数据比较,以此来提高
效率。例如:一次从外表读10行,然后读内部表时,都和这10行数据进行比较。
MySQL使用join buffer的条件为:
1,join_buffer_size系统变量决定了每个join使用的buffer大小
2,join类型为index或all时,join buffer才能被使用
3,每一个join都会分配一个join buffer,即一个sql可能使用多个join buffer
4,join buffer 不会分配给第一个非常量表
5,只有需要引用的列会被放到join buffer中,不是整行
如以下例子:
for each row in t1 matching range { for each row in t2 matching reference key { store used columns from t1, t2 in join buffer 这里将t1和t2使用的列存到join buffer中 if buffer is full { for each row in t3 { for each t1, t2 combination in join buffer { if row satisfies join conditions, send to client } } empty buffer } }}if buffer is not empty { for each row in t3 { for each t1, t2 combination in join buffer { if row satisfies join conditions, send to client } }}注:注意到一点:是在第二个循环才把数据存在join buffer中,这正好印证了上面的第4点
- 06-16卡巴斯基郑启良:支持信创发展是卡巴斯基的重要使命
- 06-16访问管理是确保现代工作场所安全的的五个关键原因
- 06-16零信任安全的演变:彻底改变网络安全策略
- 06-16GitHub上值得关注的20个网络安全项目
- 06-16英国曼彻斯特大学遭遇网络攻击,机密数据或遭窃!
- 06-16调查表明广告软件推送恶意软件感染了六万多个安卓应用程序
- 06-16微软向美国政府提供GPT的大模型,安全性如何保证?
- 06-16如何保护OT环境免受安全威胁?
- 01-11全球最受赞誉公司揭晓:苹果连续九年第一
- 12-09罗伯特·莫里斯:让黑客真正变黑
- 12-09谁闯入了中国网络?揭秘美国绝密黑客小组TA
- 12-09警示:iOS6 惊现“闪退”BUG
- 12-05亚马逊推出新一代基础模型 任意模态生成大模
- 12-05OpenAI拓展欧洲业务 将在苏黎世设立办公室
- 12-05微软质疑美国联邦贸易委员会泄露信息 督促其
- 12-05联交所取消宝宝树上市地位 宝宝树:不会对公
- 12-04企业微信致歉:文档打开异常已完成修复