MySQL之子查询

x33g5p2x  于9个月前 转载在 Mysql  
字(1.4k)|赞(0)|评价(0)|浏览(75)

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无索引

非关联查询和关联查询都一样,都需要全盘扫描,效率差不多。

相关文章

热门文章

更多