mysql in 不存在_mysql中带有in的子查询,子查询select表1存在但表2不存在的字段,出现的奇怪输出...

Mysql 子查询的实现并不是我们想象的那样。

select * from student where id in (select student_id from course);

对于上面的sql,我们一般会认为是这样执行:

猜想1:

select student_id from course;

result: 1,2,3

select * from student where id in(1,2,3)

事实上不是这样,Mysql会把外层表压入到子查询中,具体的执行计划可以使用explain extended查看:

EXPLAIN EXTENDED

select * from student where id in (select student_id from course);

SHOW WARNINGS;

select `test`.`student`.`id` AS `id`,`test`.`student`.`name` AS `name`

from `test`.`student`

where (

`test`.`student`.`id`,(select 1 from `test`.`course` where ((`test`.`student`.`id`) = `test`.`course`.`student_id`)));

Mysql处理后等价于:

select * from student where exists (select 1 from course where course.student_id = student.id);

查看执行计划,可以看到mysql对于student表全表扫描,然后按照id逐条执行子查询。这和我们的猜想1完全相反。

到现在并没有解释LZ的问题,我们可以猜想下。

猜想2:既然是先全表扫描然后逐条子查询,是不是子查询的变量都是来自全表扫描时的局部变量?我们再看一下执行计划:

EXPLAIN EXTENDED

select * from student where id in (select id from course);

show WARNINGS;

select `test`.`student`.`id` AS `id`,`test`.`student`.`name` AS `name` from `test`.`student` where (`test`.`student`.`id`,(select 1 from `test`.`course` where ((`test`.`student`.`id`) = `test`.`student`.`id`)));

通过查询计划可以清晰的看到,真正执行的时候,子查询的变量都是全表扫描时的局部变量student.id,这也就解释了“为什么course中不存在id或者name字段,子查询不报错”,是因为查询的优化,导致根本不是使用的course的id或者name字段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值