MySQL的子查询及相关优化学习教程

 更新时间:2015年11月24日 09:53  点击:2395

一、子查询
1、where型子查询
(把内层查询结果当作外层查询的比较条件)

#不用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,商品表goodsselect cat_id,cat_name from category where exists(select * from goods where goods.cat_id = category.cat_id);

二、优化
从句式的形式看,子查询分为特殊格式子查询和非特殊格式子查询,特殊格式的子查询中又包括IN、ALL、ANY、SOME、EXISTS等类型的子查询,对于有的类型的子查询,MySQL有的支持优化,有的不支持,具体情况如下。

 

示例一,MySQL不支持对EXISTS类型的子查询的优化:

EXISTS类型的相关子查询,查询执行计划如下:

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)

被查询优化器处理后的语句为:

/* 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没有进一步做子查询的优化工作。

另外的一个EXISTS类型的相关子查询,查询执行计划如下:

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)

被查询优化器处理后的语句为:

/* 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`.`b1` = `test`.`t2`.`b2`) and (`test`.`t1`.`a1` = 10)))

从查询执行计划看,子查询存在,MySQL没有进一步做子查询的优化工作。

 

示例二,MySQL不支持对NOT EXISTS类型的子查询的优化:

NOT EXISTS类型的相关子查询,查询执行计划如下:

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, 2 warnings (0.00 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,  `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没有进一步做子查询的优化工作。

 

另外的一个NOT EXISTS类型的相关子查询,查询执行计划如下:

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)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,  `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支持对IN类型的子查询的优化,按也有不支持的情况存在:

IN非相关子查询,查询执行计划如下:

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)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,  `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子查询优化为半连接操作。

 

另外一个IN非相关子查询,查询执行计划如下:

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)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,  `test`.`t1`.`b1` AS `b1`from `test`.`t1` semi join (`test`.`t2`)where ((`<subquery2>`.`a2` = 10) and (`test`.`t1`.`a1` = 10) and (`test`.`t2`.`a2` = 10))

从查询执行计划看,子查询不存在,表t1和t2直接做了块嵌套循环半连接(Block Nested Loop),把子查询上拉到父查询中用嵌套循环半连接完成IN操作。另外,由于子查询上拉,使得增加连接条件“a1=a2”,而原先的条件“a2=10”可以利用常量传递优化技术,使得“a1=a2=10”,所以查询执行计划中,两个索引扫描的条件分别为:a1 = 10、a2 = 10。

 

另外一个IN非相关子查询,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 IN (SELECT a2 FROM t2 WHERE t1.a1=10);
+----+-------------+-------+------+------------------------------------------------------------------+| id | select_type | table | type | Extra      |+----+-------------+-------+------+------------------------------------------------------------------+| 1 | SIMPLE   | t2  | ALL | Using where; Start temporary      || 1 | SIMPLE   | t1  | ALL | Using where; End temporary; Using join buffer (Block Nested Loop)|+----+-------------+-------+------+------------------------------------------------------------------+2 rows in set, 2 warnings (0.00 sec)

被查询优化器处理后的语句为:
/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,  `test`.`t1`.`b1` AS `b1`from `test`.`t1` semi join (`test`.`t2`)where ((`test`.`t2`.`a2` = 10) and (`test`.`t1`.`a1` = 10))

从查询执行计划看,子子查询不存在,表t1和t2直接做了块嵌套循环连接(Block Nested Loop),但属于半连接操作(semi join),把子查询上拉到父查询中用嵌套循环半连接完成IN操作。

 

示例四,MySQL支持对NOT IN类型的子查询的优化

NOT IN非相关子查询,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 NOT IN (SELECT a2 FROM t2 WHERE t2.a2>10);
+----+-------------+-------+------+------+-------------+| id | select_type | table | type | key | Extra    |+----+-------------+-------+------+------+-------------+| 1 | PRIMARY   | t1  | ALL | NULL | Using where || 2 | SUBQUERY  | t2  | ALL | NULL | Using where |+----+-------------+-------+------+------+-------------+2 rows in set, 1 warning (0.02 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`from `test`.`t1`where (not(<in_optimizer>(  `test`.`t1`.`a1`,`test`.`t1`.`a1` in (    <materialize> (/* select#2 */      select `test`.`t2`.`a2`      from `test`.`t2`      where (`test`.`t2`.`a2` > 10)      having 1    ),    <primary_index_lookup>(      `test`.`t1`.`a1` in <temporary table> on <auto_key>      where ((`test`.`t1`.`a1` = `materialized-subquery`.`a2`))    )   )  )))

从查询执行计划看,表t2做了子查询(SUBQUERY)。而子查询被物化(materialize)。所以,MySQL对于NOT IN子查询采用了物化的优化方式,但不支持子查询的消除。

 

另外一个NOT IN非相关子查询,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 NOT IN (SELECT a2 FROM t2 WHERE t2.a2=10);
+----+-------------+-------+------+------+-------------+| id | select_type | table | type | key | Extra    |+----+-------------+-------+------+------+-------------+| 1 | PRIMARY   | t1  | ALL | NULL | Using where || 2 | SUBQUERY  | t2  | ALL | NULL | Using where |+----+-------------+-------+------+------+-------------+2 rows in set, 1 warning (0.00 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`from `test`.`t1`where (not(<in_optimizer>(  `test`.`t1`.`a1`,`test`.`t1`.`a1` in (    <materialize> (/* select#2 */      select `test`.`t2`.`a2`      from `test`.`t2`      where (`test`.`t2`.`a2` = 10)      having 1    ),    <primary_index_lookup>(      `test`.`t1`.`a1` in <temporary table> on <auto_key>      where ((`test`.`t1`.`a1` = `materialized-subquery`.`a2`))    )  )  )))

从查询执行计划看,表t2做了子查询(SUBQUERY)。而子查询被物化(materialize)。所以,MySQL对于NOT IN子查询采用了物化的优化方式,但不支持子查询的消除。

 

示例五,MySQL支持对ALL类型的子查询的优化:

不相关的ALL子查询,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 >ALL (SELECT a2 FROM t2 WHERE t2.a2>10);
+----+-------------+-------+------+------+-------------+| id | select_type | table | type | key | Extra    |+----+-------------+-------+------+------+-------------+| 1 | PRIMARY   | t1  | ALL | NULL | Using where || 2 | SUBQUERY  | t2  | ALL | NULL | Using where |+----+-------------+-------+------+------+-------------+2 rows in set, 1 warning (0.00 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`from `test`.`t1`where <not>((`test`.`t1`.`a1` <= <max>(  /* select#2 */  select `test`.`t2`.`a2`  from `test`.`t2`  where (`test`.`t2`.`a2` > 10)  )))

从查询执行计划看,出现了子查询(SUBQUERY),但是,子查询被“<= <max>”操作符限制,而子查询中的被查询列a2上存在唯一索引,所以可以利用索引求最值,所以MySQL支持“>ALL”式的子查询优化,子查询只被执行一次即可求得最大值。

 

不相关的ALL子查询,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 =ALL (SELECT a2 FROM t2 WHERE 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, 1 warning (0.00 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`from `test`.`t1`where <not>(<in_optimizer>(  `test`.`t1`.`a1`,<exists>(    /* select#2 */ select 1 from `test`.`t2`    where ((`test`.`t2`.`a2` = 10) and      <if>(outer_field_is_not_null,        ((<cache>(`test`.`t1`.`a1`) <> 10) or <cache>(isnull(10))),        true      )    )    having <if>(outer_field_is_not_null, <is_not_null_test>(`test`.`t2`.`a2`), true)  )))

从查询执行计划看,出现了子查询(SUBQUERY),但是被查询优化器处理后的语句中包含“exists”,这表明MySQL对于“=ALL”式的子查询优化用“EXISTS strategy”方式优化,所以MySQL支持“=ALL”式的子查询优化。

 

不相关的ALL子查询,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 <ALL (SELECT a2 FROM t2 WHERE t2.a2=10);
+----+-------------+-------+------+------+-------------+| id | select_type | table | type | key | Extra    |+----+-------------+-------+------+------+-------------+| 1 | PRIMARY   | t1  | ALL | NULL | Using where || 2 | SUBQUERY  | t2  | ALL | NULL | Using where |+----+-------------+-------+------+------+-------------+2 rows in set, 1 warning (0.00 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`from `test`.`t1`where <not>((`test`.`t1`.`a1` >= <min>  (/* select#2 */    select `test`.`t2`.`a2`    from `test`.`t2`    where (`test`.`t2`.`a2` = 10)  )))

从查询执行计划看,出现了子查询(SUBQUERY),但是,子查询被“>= <min>”操作符限制,而子查询中的被查询列a2上存在唯一索引,所以可以利用索引求最值,所以MySQL支持“<ALL”式的子查询优化,子查询只被执行一次即可求得最小值。

 

示例六,MySQL支持对SOME类型的子查询的优化:

使用了“>SOME”式子的子查询被优化,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 >SOME (SELECT a2 FROM t2 WHERE t2.a2>10);
+----+-------------+-------+------+------+-------------+| id | select_type | table | type | key | Extra    |+----+-------------+-------+------+------+-------------+| 1 | PRIMARY   | t1  | ALL | NULL | Using where || 2 | SUBQUERY  | t2  | ALL | NULL | Using where |+----+-------------+-------+------+------+-------------+2 rows in set, 1 warning (0.05 sec)

被查询优化器处理后的语句为:

 /* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,   `test`.`t1`.`b1` AS `b1`from `test`.`t1`where <nop>((`test`.`t1`.`a1` > (  /* select#2 */  select min(`test`.`t2`.`a2`)  from `test`.`t2`  where (`test`.`t2`.`a2` > 10))))

从查询执行计划看,出现了子查询(SUBQUERY),但是,子查询被“min”函数限制,而子查询中的被查询列a2上存在唯一索引,所以可以利用索引求最值,所以MySQL支持“>SOME”式的子查询优化,子查询只被执行一次即可求得最大值。

 

使用了“=SOME”式子的子查询被优化,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 =SOME (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.01 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,`test`.`t1`.`b1` AS `b1`from `test`.`t1` semi join (`test`.`t2`)where ((`<subquery2>`.`a2` = 10) and (`test`.`t1`.`a1` = 10) and (`test`.`t2`.`a2` = 10))

从查询执行计划看,没有出现了子查询,表t2被物化,与表t1进行了半连接。

 

使用了“<SOME”式子的子查询被优化,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 <SOME (SELECT a2 FROM t2 WHERE t2.a2=10);
+----+-------------+-------+------+------+-------------+| id | select_type | table | type | key | Extra    |+----+-------------+-------+------+------+-------------+| 1 | PRIMARY   | t1  | ALL | NULL | Using where || 2 | SUBQUERY  | t2  | ALL | NULL | Using where |+----+-------------+-------+------+------+-------------+2 rows in set, 1 warning (0.00 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,  `test`.`t1`.`b1` AS `b1`from `test`.`t1`where <nop>(  (    `test`.`t1`.`a1` < (/* select#2 */      select max(`test`.`t2`.`a2`)      from `test`.`t2`      where (`test`.`t2`.`a2` = 10)    )  ))

从查询执行计划看,出现了子查询(SUBQUERY),但是,子查询被“max”函数限制,而子查询中的被查询列a2上存在唯一索引,所以可以利用索引求最值,所以MySQL支持“<SOME”式的子查询优化,子查询只被执行一次即可求得最大值。

 

示例七,MySQL支持对ANY类型的子查询的优化:

使用了“>ANY”式子的子查询被优化,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 >ANY (SELECT a2 FROM t2 WHERE t2.a2>10);
+----+-------------+-------+------+------+-------------+| id | select_type | table | type | key | Extra    |+----+-------------+-------+------+------+-------------+| 1 | PRIMARY   | t1  | ALL | NULL | Using where || 2 | SUBQUERY  | t2  | ALL | NULL | Using where |+----+-------------+-------+------+------+-------------+2 rows in set, 1 warning (0.00 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,  `test`.`t1`.`b1` AS `b1`from `test`.`t1`where <nop>(  (    `test`.`t1`.`a1` > (/* select#2 */      select min(`test`.`t2`.`a2`)      from `test`.`t2`      where (`test`.`t2`.`a2` > 10)    )  ))

从查询执行计划看,出现了子查询(SUBQUERY),但是,子查询被“min”函数限制,而子查询中的被查询列a2上存在唯一索引,所以可以利用索引求最值,所以MySQL支持“>ANY”式的子查询优化,子查询只被执行一次即可求得最小值。

 

使用了“=ANY”式子的子查询被优化,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 =ANY (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.02 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,  `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进行了半连接。

 

使用了“<ANY”式子的子查询被优化,查询执行计划如下:

mysql> EXPLAIN EXTENDED SELECT * FROM t1 WHERE t1.a1 <ANY (SELECT a2 FROM t2 WHERE t2.a2>10);
+----+-------------+-------+------+------+-------------+| id | select_type | table | type | key | Extra    |+----+-------------+-------+------+------+-------------+| 1 | PRIMARY   | t1  | ALL | NULL | Using where || 2 | SUBQUERY  | t2  | ALL | NULL | Using where |+----+-------------+-------+------+------+-------------+2 rows in set, 1 warning (0.00 sec)

被查询优化器处理后的语句为:

/* select#1 */ select `test`.`t1`.`id1` AS `id1`,`test`.`t1`.`a1` AS `a1`,  `test`.`t1`.`b1` AS `b1`from `test`.`t1`where <nop>(  (    `test`.`t1`.`a1` < (/* select#2 */      select max(`test`.`t2`.`a2`)      from `test`.`t2`      where (`test`.`t2`.`a2` > 10)    )  ))

从查询执行计划看,出现了子查询(SUBQUERY),但是,子查询被“max”函数限制,而子查询中的被查询列a2上存在唯一索引,所以可以利用索引求最值,所以MySQL支持“<ANY”式的子查询优化,子查询只被执行一次即可求得最大值。

[!--infotagslink--]

相关文章

  • Mybatis Plus select 实现只查询部分字段

    这篇文章主要介绍了Mybatis Plus select 实现只查询部分字段的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-01
  • MyBatisPlus-QueryWrapper多条件查询及修改方式

    这篇文章主要介绍了MyBatisPlus-QueryWrapper多条件查询及修改方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2022-06-27
  • Oracle使用like查询时对下划线的处理方法

    这篇文章主要介绍了Oracle使用like查询时对下划线的处理方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-16
  • 解决mybatis-plus 查询耗时慢的问题

    这篇文章主要介绍了解决mybatis-plus 查询耗时慢的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-04
  • Mysql效率优化定位较低sql的两种方式

    关于mysql效率优化一般通过以下两种方式定位执行效率较低的sql语句。通过慢查询日志定位那些执行效率较低的 SQL 语句,用 --log-slow-queries[=file_name] 选项启动时, mysqld 会 写一个包含所有执行时间超过 long_quer...2015-11-08
  • Android用MemoryFile文件类读写进行性能优化

    java开发的Android应用,性能一直是一个大问题,,或许是Java语言本身比较消耗内存。本文我们来谈谈Android 性能优化之MemoryFile文件读写。 Android匿名共享内存对外A...2016-09-20
  • MySQL针对Discuz论坛程序的基本优化教程

    过了这么久,discuz论坛的问题还是困扰着很多网友,其实从各论坛里看到的问题总结出来,很关键的一点都是因为没有将数据表引擎转成InnoDB导致的,discuz在并发稍微高一点的环境下就表现的非常糟糕,产生大量的锁等待,这时候如果...2015-11-24
  • 101个MySQL的配置和优化以及备份的经验提示

    MySQL是一个功能强大的开源数据库。随着越来越多的数据库驱动的应用程序,人们一直在推动MySQL发展到它的极限。这里是101条调节和优化 MySQL安装的技巧。一些技巧是针对特定的安装环境的,但这些思路是通用的。我已经把...2013-09-11
  • Angular性能优化之第三方组件和懒加载技术

    这篇文章主要介绍了Angular性能优化之第三方组件和懒加载技术,对性能优化感兴趣的同学,可以参考下...2021-05-11
  • MySQL中在查询结果集中得到记录行号的方法

    如果需要在查询语句返回的列中包含一列表示该条记录在整个结果集中的行号, ISO SQL:2003 标准提出的方法是提供 ROW_NUMBER() / RANK() 函数。 Oracle 中可以使用标准方法(8i版本以上),也可以使用非标准的 ROWNUM ; MS SQL...2015-03-15
  • Node实现搜索框进行模糊查询

    这篇文章主要为大家详细介绍了Node实现搜索框进行模糊查询,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-06-28
  • C#程序优化-有效减少CPU占用率

    本文给大家介绍的是C#程序优化的小技巧,通过此方法可以有效的降低CPU的占用率,十分的简单实用,有需要的小伙伴可以参考下。...2020-06-25
  • 利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化)

    这篇文章主要介绍了利用 Chrome Dev Tools 进行页面性能分析的步骤说明(前端性能优化),本文给大家介绍的非常想详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-02-24
  • Mybatis用注解写in查询的实现

    这篇文章主要介绍了Mybatis用注解写in查询的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-13
  • PHP+Mysql+jQuery查询和列表框选择操作实例讲解

    本文讲解如何通过ajax查询mysql数据,并将返回的数据显示在待选列表中,再通过选择最终将选项加入到已选区,可以用在许多后台管理系统中。本文列表框的操作依赖jquery插件。HTML <form id="sel_form" action="post.php" me...2015-10-23
  • 网站广告怎么投放最好?首屏广告投放类型优化和广告位布局优化的案例

    网站广告怎么投放最好?一个网站中广告位置最好的是哪几个地方呢,许多的朋友都不知道如何让自己的网站广告收效最好了,今天我们就一起来看看吧。 在说到联盟优化前,...2016-10-10
  • Mybatis和Mybatis-Plus时间范围查询方式

    这篇文章主要介绍了Mybatis和Mybatis-Plus时间范围查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-06
  • mysql like查询字符串示例语句

    MySQL提供标准的SQL模式匹配,以及一种基于象Unix实用程序如vi、grep和sed的扩展正则表达式模式匹配的格式 一、SQL模式SQL的模式匹配允许你使用“_”匹配任何单个字符,而“%”匹配任意数目字符(包括零个字符)。在 MySQL...2013-10-04
  • JPA如何使用nativequery多表关联查询返回自定义实体类

    这篇文章主要介绍了JPA如何使用nativequery多表关联查询返回自定义实体类,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-11-18
  • C#百万数据查询出现超时问题的解决方法

    这篇文章主要介绍了C#百万数据查询出现超时问题的解决方法,是非常实用的技巧,需要的朋友可以参考下...2020-06-25