zoukankan      html  css  js  c++  java
  • Mysql执行计划-selectType

     一、执行计划列输出说明

      

    二、select_type 查询的类型

      

    1、simple

      SIMPLE 最简单的查询方式

    EXPLAIN select * from myshop.ecs_users where user_id =1;

      输出

    2、PRIMARY

      PRIMARY 最外层开始查询

      UNION,UNION 第一个SELECT 为PRIMARY,第二个及之后的所有SELECT 为 UNION SELECT TYPE;

      UNION RESULT,每个结果集的取出来后,会做合并操作,这个操作就是 UNION RESULT

    EXPLAIN select * from myshop.ecs_users where user_id =1 union select * from myshop.ecs_users where user_id =2;

      输出

      根据 id 越大,优先级越大,也就是 id 为 2 的先查询,即 union 后半部分先执行。

      id 为 2 的查询类型为UNION。根据上面说明,第一个SELECT 为PRIMARY,第二个及之后的所有SELECT 为 UNION SELECT TYPE;

      然后 id 为 1 的再执行查询;

      最后一行表示不查询,只是将两个结果集合并。

    3、 DEPENDENT UNION

      DEPENDENT UNION,子查询中的UNION操作,从UNION 第二个及之后的所有SELECT语句的SELECT TYPE为 DEPENDENT UNION

      DEPENDENT SUBQUERY,子查询中内层的第一个SELECT,依赖于外部查询的结果集

    EXPLAIN select * from myshop.ecs_users where user_id in (
     select user_id from myshop.ecs_users where user_id =1 union select user_id from myshop.ecs_users where user_id =2);

      输出

      首先,查询的是括号里面的查询语句的union 后面那部分,也用到主键索引

      第二个查询的是 id 为 2 的那个,也用到主键索引,即括号里面第一部分,union 前面那部分查询

      到输出最后一行,显示将第二个查询和第三个查询合并;

      最后执行 id 为 1 的查询, 可以看到,这条查询,并没有用到任何索引。

    4、DERIVED 

      DERIVED 派生表,子查询在 FROM子句中

    EXPLAIN select * from myshop.ecs_users a,
        (select max(user_id) as user_id, CURRENT_DATE() from myshop.ecs_users where email is null ) b
        where a.user_id = b.user_id;

    -- mysql不会为每个子查询都创建派生表,派生表的目的就是用于保存子查询的中间结果

    -- 此语句优化后无子查询(子查询展开) EXPLAIN select * from (select user_id from myshop.ecs_users where user_id =1) as a;

    -- 默认开启,优化器工作 可以关闭 set optimizer_switch='derived_merge=off';

       输出

      先查询,优先级最高的 id 为 2 的查询,生成一张临时表 

      然后,两个 select  id 为 1 的一样,就先从上到下,查询。

    5、MATERIALIZED

      MATERIALIZED 物化子查询

      可以当作做成一个临时表,比如,下面 in 后面括号里面的查询

    EXPLAIN select * from myshop.ecs_users 
        where user_id in (
            SELECT USER_ID FROM myshop.ecs_order_info where order_id < 10 );

      输出

      先执行,id为2, 查询 ecs_order_info 生成一张临时表

      先执行,id 为 1 (上面的哪条)的那条查询,叫 <subquery2>, type 为 ALL, 全部查询出来

      再执行最后一个 id 为1 的查询

     6、UNCACHEABLE SUBQUERY

      从 MySQL 5.7.20开始,查询缓存就被弃用了,并在 MySQL 8.0中被删除。

      UNCACHEABLE SUBQUERY 结果集不能被缓存的子查询,不可物化每次都需要计算(动态计算,耗时操作)

    EXPLAIN select * from myshop.ecs_users where user_id = (
        select max(LAST_INSERT_ID()) as user_id from myshop.ecs_users);

      输出

      id = 2, 先得到一个不能被缓存的子查询

      

    7、UNCACHEABLE UNION UNION

      UNCACHEABLE UNION UNION中第二个语句或后面的语句属于不可缓存的子查询

    EXPLAIN select * from myshop.ecs_users where user_id = (
        select max(LAST_INSERT_ID()) as user_id from myshop.ecs_users
        union select max(LAST_INSERT_ID()) as user_id from myshop.ecs_users);

      输出

    ----------------------------------

    [1] https://www.jianshu.com/p/3111f83663d7

  • 相关阅读:
    MySQL性能优化
    mysql中OPTIMIZE TABLE的作用
    Linux中/usr与/var目录详解
    Mysql之EXPLAIN显示using filesort
    MySQL ALTER语法的运用方法 && 操作索引和字段
    NoSQL数据库的分布式算法&&memcache集群的实现
    linux用户权限
    hdoj1241 Oil Deposits
    ny42 一笔画问题
    ny20 吝啬的国度
  • 原文地址:https://www.cnblogs.com/Jomini/p/14099284.html
Copyright © 2011-2022 走看看