MySQL可以执行子查询,也就是在查询中嵌套查询
子查询分为两类:关联子查询和非关联子查询
假设系统现在有两个表,分别为 user 和 order。
user 为用户表,有id,name两个字段
order为订单表,有oid,userid两个字段。
我们现在需要求出所有买过东西的用户的name。
非关联子查询 指的是 子查询 的查询条件 不依赖于 外部查询的数据
select name from user where user.id in (select userid from order);
上面的代码可以查出 所有买过东西的用户的name。
子查询中没有用到 外部 查询的数据,属于非关联子查询。
非关联子查询的流程如下:
1、执行子查询,得到order中对应的所有userid。
2、遍历order中得到的userid,到user中执行外部查询,也就是执行select name from user where user.id = userid.如果能查出对应的name,就将name返回给客户端
关联子查询 指的是 子查询 的查询条件 依赖于 外部查询的数据
select name from user exists(select * from order where order.userid = user.id)
上面的代码可以查出 所有买过东西的用户的name。
子查询中需要用到 外部 查询的数据 user.id ,属于非关联子查询。
关联子查询的流程如下:
1、执行外部查询,一条一条的取出user中的记录,拿出其中的id
2、根据记录中的id,执行内部查询,select /* from order where order.userid = id。如果能查出对应的记录,就将对应的name返回给客户端。
关联子查询和非关联子查询 哪个 效率更高呢?
select name from user where user.id in (select userid from order);
select name from user exists(select * from order where order.userid = user.id)
1、user的id有索引,order的userid无索引
in 非关联子查询效率高,因为可以使用user的id索引
如果外部查询有索引,但是内存查询没有索引,最好采用 非关联查询
2、user的id无索引,order的userid有索引
exists 关联子查询效率高,可以使用order的userid索引
如果外部查询无索引,但是内存查询有索引,最好采用 关联查询
3、user的id有索引,order的userid有索引
这个时候需要比较 user 和 order的规模,
如果user表较大,in 非关联查询效率高,因为二者都有索引,但是in 非关联查询 是 将 order表中全表扫描,然后到user表中利用索引直接查询得到对应的结果,不用对user全盘扫描。这时只需要扫描 order表中的少数的记录。
如果采用 exists的话, 需要对 user表 全表扫描,然后到 order表中利用索引查询,不需要对order全盘扫描,但是这个时候需要扫描 user表中的多数的记录。
所以当外部查询的数据多时,最好采用 非关联查询
所以当外部查询的数据少时,最好采用 关联查询
3、user的id无索引,order的userid无索引
非关联查询和关联查询都一样,都需要全盘扫描,效率差不多。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/qq_40276626/article/details/120791646
内容来源于网络,如有侵权,请联系作者删除!