子查询与关联查询区别

Posted minikobe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了子查询与关联查询区别相关的知识,希望对你有一定的参考价值。

1.子查询
1.1. mysql从4.1版本开始支持子查询,使用子查询进行SELECT语句嵌套查询,可以一次完成很多逻辑上需要多个步骤才能完成的SQL操作
1.2.子查询虽然很灵活,但是执行效率并不高
1.3.执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,这里多了一个创建和销毁临时表的过程
2.连接查询(join)
2.1.可以使用连接查询(JOIN)代替子查询,连接查询不需要建立临时表,因此其速度比子查询快
总结:连接查询效率高于子查询!!!
扩展:多表联查性能优化
优化的本质就是(join on 和where的执行顺序)!!!
1.数据库在通过连接两张或多张表来返回记录时,都会生成一张 中间的临时表,然后再将这张临时表返回给用户
注意:这张临时表是数据库(MySQL自动生成)
2.在使用left jion on时,on和where条件的区别如下:

2.1.on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录
2.2.where条件是在临时表生成好后,再对临时表进行过滤的条件(这时已经和left join没关系了),条件不为真的就全部过滤掉
1
2
3.left join on + where条件查询的索引优化实例分析:
sql:select * from A left join B on A.c = B.c where A.employee_id = 3
解读: A表left join B表,并且指定A表中的employee_id为一个具体的值

3.1.假设A表,B表均有10000多条数据;
3.2.使用上面的sql查询时间达到16秒(在c字段不是任何索引,用explain分析得知,AB表都使用了全表查询,效率极低)
3.3.开始优化上面sql
(1)给AB表列c都加索引(仅用了0.1s,但是分析后显示表A依然进行了全表扫描)
思考:为什么全表扫描的不是表B
因为Mysql内部的优化,使用小表驱动大表,它在估算到必须有一个表要全表扫描的话,一定会选择那个数据量更小的表去全表扫描,
也就是说,在这个查询中,因为on以后的where条件列并没有使用到索引,所以mysql的优化只用到了表B的c索引,没有用到表A的索引!
(2)我们有where条件查询,不需要全表扫描,此时就需要where条件生效,操作及分析如下:
1.将A表中的索引改为employee_id+c(经验证两个所以都使用了,方案可行)
思考:sql执行 from中的on应该是优先于where语句的,为什么这里employee_id反而在c之前,有违常理
因为Mysql内部优化,这一句Sql在执行的时候首先是选择了使用表B的索引来进行优化,将表A单独放出来进行后续的操作,
然后,又发现了where语句中A.employee_id有一个聚合索引,并且employee_id处于索引头,所以这个聚合索引是可用的,所以自然使用了此索引
2.即使把聚合索引后面的列c删掉,与使用聚合索引的效果是一样的,之前全表查询,现在根据条件只查询了满足条件的,时间大幅缩短

扩展:mysql连接查询中索引的重要性
1.连接查询通过两张表中符合连接关系的字段来建立两张表的关联,通常包括内连接、左外连接、右外连接和全连接
2.内连接会保留两张表中共有的那部分记录,因此最后产生的连接表记录数最少;
全连接会保留两张表中所有的记录,因此最后产生的连接表记录数最多;
左外连接会保留左表的全部记录,右外连接会保留右表的全部记录,因此最后产生的连接表记录数处于内连接和外连接之间。
3.我们可以给关联表的字段添加索引来减少查询次数,提高查询效率
4.使用多表关联时,一般遵循以下规则:
4.1.左连接:一般给右边表的关联字段建立索引;
4.2.右关联:一般给左边表的关联字段建立索引;
4.3.内连接:一般给关联表的任意一边的关联字段建立索引即可

举例:学生表student(id,name),课程表class(id,student_id,class),各有10000条数据
sql实例:SELECT a.id, name FROM student a
LEFT JOIN class b ON a.id = b.student_id
这个查询的执行速度非常慢!!
1.首先用explain查看这个语句的查询执行计划,可以看到type都为ALL,即在student表和class表中都使用的全表扫描
2.改进:试着给class表的student_id字段添加索引
alter table class add index class_index(student_id)
3.然后再次执行查询,发现速度非常快,这就是效率改进的关键点所在
4.当连接查询时产生的连接表过大时,为了防止查询次数过多,我们要经常使用索引来减少查询次数,提高查询效率
————————————————
版权声明:本文为CSDN博主「梦断若水」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq591009234/article/details/90901869

以上是关于子查询与关联查询区别的主要内容,如果未能解决你的问题,请参考以下文章

第五章 复杂查询 5-3 关联子查询

SQL关联查询 直接join 和子查询的区别

子查询与关联查询哪个效果高

SQL基础教程(第2版)第5章 复杂查询:5-3 关联子查询

sql中in和exist语句的区别?

oracle sql 转换成 hive sql -子查询转关联查询(十七),子查询中有2个表外字段关联写法,round函数与power函数的运用