暂无图片
mysql自查询中有主键使用in和主键使用=的区别
我来答
分享
暂无图片 匿名用户
mysql自查询中有主键使用in和主键使用=的区别

原查询

select * from t where t.id in (select max(id) from t where t.name='xxx' and t.age=11);自查询由于有name索引只扫描1行就能查到结果,但是主键却使用扫描全表。将语句换成select * from t where t.id = (select max(id) from t where t.name='xxx' and t.age=11);后语句均扫描1行即可得到结果。这是为什么?

我来答
添加附件
收藏
分享
问题补充
3条回答
默认
最新
伟鹏

select * from t where t.id in (select max(id) from t where t.name='xxx' and t.age=11);  是一个半连接查询“ (select max(id) from t where t.name='xxx' and t.age=11)” 是一个子查询,()里的表作为驱动表,驱动表查询一次,被驱动表T就会做一次全表扫描。

select * from t where t.id = (select max(id) from t where t.name='xxx' and t.age=11);”  作为等值连接,走索引扫描。


暂无图片 评论
暂无图片 有用 4
广州_老虎刘

首先是sql写法的问题, 既然已知子查询只会返回一条记录, 那就不应该写in, 直接写=, 效率是没问题的, 这种是最简单的自关联,如果改用order by id desc limit 1, 效率还能更高一点;  

其次是mysql优化器的问题, 它的查询转换规则有点少, oracle和pg对这种in的写法也可以得到高效的执行计划.  优化器水平不行, 对SQL写法的要求就更高, 像 select * from t1 a where id = (select max(id) from t1 b where a.owner=b.owner); 这种自关联写法的SQL,  mysql基本上就完全蒙圈了, pg比myql强点, 最好的执行计划还是oracle.

暂无图片 评论
暂无图片 有用 0
chengang

外表和子查询的表 都是t 所以我们从语句中无法看出是关联子查询还是非关联子查询


暂无图片 评论
暂无图片 有用 0
回答交流
提交
问题信息
请登录之后查看
邀请回答
暂无人订阅该标签,敬请期待~~
暂无图片墨值悬赏