<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        MySQL的子查詢及相關優化學習教程

        來源:懂視網 責編:小采 時間:2020-11-09 20:55:28
        文檔

        MySQL的子查詢及相關優化學習教程

        MySQL的子查詢及相關優化學習教程:一、子查詢 1、where型子查詢 (把內層查詢結果當作外層查詢的比較條件) #不用order by 來查詢最新的商品 select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods); #取出
        推薦度:
        導讀MySQL的子查詢及相關優化學習教程:一、子查詢 1、where型子查詢 (把內層查詢結果當作外層查詢的比較條件) #不用order by 來查詢最新的商品 select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods); #取出

        一、子查詢
        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,商品表goods
        select 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”式的子查詢優化,子查詢只被執行一次即可求得最大值。

        您可能感興趣的文章:

      1. MySQL優化之使用連接(join)代替子查詢
      2. MYSQL子查詢和嵌套查詢優化實例解析
      3. mysql in語句子查詢效率慢的優化技巧示例
      4. mysql優化系列 DELETE子查詢改寫優化
      5. mysql關聯子查詢的一種優化方法分析
      6. Oracle數據庫中基本的查詢優化與子查詢優化講解
      7. 對MySQL子查詢的簡單改寫優化
      8. 淺談MySQL中的子查詢優化技巧
      9. MySQL查詢優化:用子查詢代替非主鍵連接查詢實例介紹
      10. 數據庫查詢優化之子查詢優化
      11. 聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        MySQL的子查詢及相關優化學習教程

        MySQL的子查詢及相關優化學習教程:一、子查詢 1、where型子查詢 (把內層查詢結果當作外層查詢的比較條件) #不用order by 來查詢最新的商品 select goods_id,goods_name from goods where goods_id = (select max(goods_id) from goods); #取出
        推薦度:
        標簽: 教程 mysql 優化
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 国产免费av片在线看| 热99RE久久精品这里都是精品免费 | 久久精品无码一区二区三区免费| 亚洲av日韩av激情亚洲| 日本高清免费观看| 亚洲AV无码成人精品区蜜桃| 美女内射无套日韩免费播放| 久久亚洲国产午夜精品理论片| 国内精品免费视频精选在线观看 | 久久久无码精品亚洲日韩蜜臀浪潮| 午夜精品一区二区三区免费视频| 亚洲激情在线观看| 最近中文字幕免费完整| 亚洲videos| 免费羞羞视频网站| xxxxxx日本处大片免费看| 亚洲精品V欧洲精品V日韩精品| 最近免费中文字幕MV在线视频3| 亚洲精品无码久久久久久久 | 亚洲无码在线播放 | 我们的2018在线观看免费高清| 亚洲色在线无码国产精品不卡| 在线免费观看韩国a视频| jizz在线免费观看| 精品亚洲成a人片在线观看少妇| 最近高清国语中文在线观看免费| 午夜在线亚洲男人午在线| 狠狠综合久久综合88亚洲| 19禁啪啪无遮挡免费网站| 亚洲国产一区二区三区在线观看| 亚洲AV蜜桃永久无码精品| 精品亚洲永久免费精品| 亚洲人成网亚洲欧洲无码| 亚洲女同成av人片在线观看| 色窝窝免费一区二区三区| 深夜A级毛片视频免费| 91亚洲国产成人久久精品网站| 性感美女视频免费网站午夜| 中文字幕在线免费播放| 亚洲熟伦熟女专区hd高清| 亚洲精品夜夜夜妓女网|