Mysql学习MySQL的子查询及相关优化学习教程
《Mysql学习MySQL的子查询及相关优化学习教程》要点: 一、子查询 #不用order by 来查询最新的商品 select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods); #取出每个栏目下最新的产品(goods_id唯一) select cat_id,goods_id,goods_name from goods where goods_id in(select max(goods_id) from goods group by cat_id); 2、from型子查询 #先查出哪些同学挂科两门以上 select name,count(*) as gk from stu where score < 60 having gk >=2; #以上查询结果,我们只要名字就可以了,所以再取一次名字 select name from (select name,count(*) as gk from stu having gk >=2) as t; #找出这些同学了,那么再计算他们的平均分 select name,avg(score) from stu where name in (select name from (select name,count(*) as gk from stu having gk >=2) as t) group by name; 3、exists型子查询 #查询哪些栏目下有商品,栏目表category,商品表goods select cat_id,cat_name from category where exists(select * from goods where goods.cat_id = category.cat_id); 二、优化 MYSQL学习 示例一,MySQL不支持对EXISTS类型的子查询的优化:MYSQL学习 EXISTS类型的相关子查询,查询执行计划如下:MYSQL学习 mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t1.a1= t2.a2 AND t2.a2>10); +----+--------------------+-------+------+------+-------------+ | id | select_type | table | type | key | Extra | +----+--------------------+-------+------+------+-------------+ | 1 | PRIMARY | t1 | ALL | NULL | Using where | | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | Using where | +----+--------------------+-------+------+------+-------------+ 2 rows in set,2 warnings (0.00 sec) 被查询优化器处理后的语句为:MYSQL学习 /* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1` from `test`.`t1` where exists(/* select#2 */ select 1 from `test`.`t2` where ((`test`.`t1`.`a1` = `test`.`t2`.`a2`) and (`test`.`t2`.`a2` > 10)) ) 从查询执行计划看,子查询存在,MySQL没有进一步做子查询的优化工作.MYSQL学习 另外的一个EXISTS类型的相关子查询,查询执行计划如下:MYSQL学习 mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t1.b1= t2.b2 AND t1.a1=10); +----+--------------------+-------+------+------+-------------+ | id | select_type | table | type | key | Extra | +----+--------------------+-------+------+------+-------------+ | 1 | PRIMARY | t1 | ALL | NULL | Using where | | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | Using where | +----+--------------------+-------+------+------+-------------+ 2 rows in set,3 warnings (0.02 sec) 被查询优化器处理后的语句为:MYSQL学习 /* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`b1` AS `b1` from `test`.`t1` where exists(/* select#2 */ select 1 from `test`.`t2` where ((`test`.`t1`.`b1` = `test`.`t2`.`b2`) and (`test`.`t1`.`a1` = 10)) ) 从查询执行计划看,MySQL没有进一步做子查询的优化工作.MYSQL学习 MYSQL学习 示例二,MySQL不支持对NOT EXISTS类型的子查询的优化:MYSQL学习 NOT EXISTS类型的相关子查询,查询执行计划如下:MYSQL学习 mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t1.a1= t2.a2 AND t2.a2>10); +----+--------------------+-------+------+------+-------------+ | id | select_type | table | type | key | Extra | +----+--------------------+-------+------+------+-------------+ | 1 | PRIMARY | t1 | ALL | NULL | Using where | | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | Using where | +----+--------------------+-------+------+------+-------------+ 2 rows in set,`test`.`t1`.`b1` AS `b1` from `test`.`t1` where (not(exists( /* select#2 */ select 1 from `test`.`t2` where ((`test`.`t1`.`a1` = `test`.`t2`.`a2`) and (`test`.`t2`.`a2` > 10)))) ) 从查询执行计划看,MySQL没有进一步做子查询的优化工作.MYSQL学习 MYSQL学习 另外的一个NOT EXISTS类型的相关子查询,查询执行计划如下:MYSQL学习 mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE NOT EXISTS (SELECT 1 FROM t2 WHERE t1.b1= t2.b2 AND t1.a1=10); +----+--------------------+-------+------+------+-------------+ | id | select_type | table | type | key | Extra | +----+--------------------+-------+------+------+-------------+ | 1 | PRIMARY | t1 | ALL | NULL | Using where | | 2 | DEPENDENT SUBQUERY | t2 | ALL | NULL | Using where | +----+--------------------+-------+------+------+-------------+ 2 rows in set,3 warnings (0.00 sec) 被查询优化器处理后的语句为:MYSQL学习 /* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`b1` AS `b1` from `test`.`t1` where (not(exists( /* select#2 */ select 1 from `test`.`t2` where ((`test`.`t1`.`b1` = `test`.`t2`.`b2`) and (`test`.`t1`.`a1` = 10)))) ) 从查询执行计划看,MySQL没有进一步做子查询的优化工作.MYSQL学习 MYSQL学习 示例三,MySQL支持对IN类型的子查询的优化,按也有不支持的情况存在:MYSQL学习 IN非相关子查询,查询执行计划如下:MYSQL学习 mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 IN (SELECT a2 FROM t2 WHERE t2.a2>10); +----+--------------+-------------+------+------+----------------------------------------------------+ | id | select_type | table | type | key | Extra | +----+--------------+-------------+------+------+----------------------------------------------------+ | 1 | SIMPLE | <subquery2> | ALL | NULL | NULL | | 1 | SIMPLE | t1 | ALL | NULL | Using where; Using join buffer (Block Nested Loop) | | 2 | MATERIALIZED | t2 | ALL | NULL | Using where | +----+--------------+-------------+------+------+----------------------------------------------------+ 3 rows in set,1 warning (0.00 sec) 被查询优化器处理后的语句为:MYSQL学习 /* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`b1` AS `b1` from `test`.`t1` semi join (`test`.`t2`) where ((`test`.`t1`.`a1` = `<subquery2>`.`a2`) and (`test`.`t2`.`a2` > 10)) 从查询执行计划看,表t2被物化后,与表t1执行了半连接(semi join).尽管有“subquery2”这样的内容看起来是子查询,但是表t2已经被上拉到表t1层执行了半连接,所以MySQL支持IN子查询优化为半连接操作.MYSQL学习 MYSQL学习 另外一个IN非相关子查询,查询执行计划如下:MYSQL学习 mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 IN (SELECT a2 FROM t2 WHERE t2.a2=10); +----+--------------+-------------+------+------+----------------------------------------------------+ | id | select_type | table | type | key | Extra | +----+--------------+-------------+------+------+----------------------------------------------------+ | 1 | SIMPLE | <subquery2> | ALL | NULL | Using where | | 1 | SIMPLE | t1 | ALL | NULL | Using where; Using join buffer (Block Nested Loop) | | 2 | MATERIALIZED | t2 | ALL | NULL | Using where | +----+--------------+-------------+------+------+----------------------------------------------------+ 3 rows in set,1 warning (0.02 sec) (编辑:莱芜站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Mysql2 ::错误:此MySQL版本不允许使用命令:LOAD DATA LOC
- Mysql必读MySQL命令行删除表中的一个字段
- ClassCastException:java.math.BigInteger在连接MySQL时无
- 远程Mysql服务器(AWS极光)上的Laravel权限被拒绝
- sql – 唯一索引减慢?
- php – Laravel查询生成器常规错误2031
- php – 使用命名占位符设置PDO / MySQL LIMIT
- Mysql实例log引起的mysql不能启动的解决方法
- mysql – 键’PRIMARY’的重复条目’…’
- Mysql应用Java连接mysql数据库并进行内容查询的方法