标量子查询希望得到自己所期望的查询值,多值子查询是期望产生一个结果的结合。
标量子查询
如 库中有表
当我们查询使用语句
select * from teacher a WHERE a.id in (SELECT id from student);
用 EXPLAIN EXTENDED 可以粗略的查看它的性能
查询结果
这样的话因为数据量少时间的差别几乎很渺小
内部 其实是 当我们在使用标量查询in 的时候,其实mysql 内部转换为了exists 下面的语句是等同的
EXPLAIN EXTENDED select * from teacher a WHERE a.id in (SELECT id from student);
EXPLAIN EXTENDED select * from teacher a WHERE a.id EXISTS (SELECT id from student);
。。
sql 内部的优化器默认的in 的使用加载时 LAZY 模式, 如果结果返回的是M列N
行,内部的扫描时间花费为其实为 Q((M+1)×N) 毫秒
(select id from student ) 虽然是独立的一个子查询结构,但在in 的语句下又转换为了相关子子查询。。Mysql 官方手册默认
sql 的默认殷勤为Innodb但是在MariaDb 5.3版本的 殷勤中提供了对独立子查询的优化甚至我们可以继续优化为
set OPTIMIZE ='Materialization=ON'
当然对于独立空间表的优化,我们还可以用optimize
innode 的殷勤优化 则先
on 代表的独立表空间开启的
然后再
这里之所以报错,因为mysql的 搜索类型的问题,
因为表的数据少,sql语句过于简单,对于表的查询类型用的simple
其实我们作为程序员,写的sql 语句几乎一大半都欠缺优化,当然不是各种项目加班,BUG等等根本没有多余的时间考虑这些问题。。
总结: 对于查询的语句,大部分都关系到多表查询,因此 我们 的原则 为: 能用派生表,绝对不用子查询和关联查询
我说的有可能比较模糊,直接上sql 吧
查询员工最大订单日期的订单 例:
(1)
(2)
(3) 派生表B 查询
(1) sql 根本不对,因为如果根据订单来,同一时间用户很有可能购置多个订单
(2) 结果正确,但效率很慢。
(3) 用派生表B,限制条件无非就一个日期,ID 吗。引入这些条件其实跟2子查询结是相同的,单效率就快的多
原因呢:因为INNO 的殷勤 它执行逻辑 IO 的大大次数减少, (2)的 逻辑IO次数可能几万次,(3)的逻辑io次则为几千次
IO的逻辑次数(在内存中Mysql 创建虚拟表,还是进行一行的比较 都算作一次逻辑IO ,创建虚拟表的时候有没有进行物理IO ??[ 这个暂时不清楚嘿嘿 ])
IO (可以暂时理解为输入输出流)