SlideShare a Scribd company logo
1 of 28
Download to read offline
MySQL
EXPLAIN
    李 玲
  2011年8月
Content
测试环境数据




MySQL执行计划




MySQL执行计划解析




Q&A
测试环境数据TPC-H
•   TPC-H是决策支持数据库的基准测试,它包含了一整套面向商业的ad-hoc查询和并发数据修改,强
    调测试的是数据库、平台和I/O性能,关注查询能力。
show index from lineitem & orders & customer
                                                                                      Index_
Table      Non_unique   Key_name         Seq_in_index   Column_name     Cardinality
                                                                                      type
lineitem   0            PRIMARY          1              l_orderkey      1500303       BTREE

lineitem   0            PRIMARY          2              l_linenumber    6001215       BTREE

lineitem   1            li_shp_dt_idx    1              l_shipdate      2525          BTREE

lineitem   1            li_com_dt_idx    1              l_commitdate    2465          BTREE

lineitem   1            li_rcpt_dt_idx   1              l_receiptdate   2553          BTREE

                                                                                      Index_
Table      Non_unique   Key_name         Seq_in_index   Column_name     Cardinality
                                                                                      type
orders     0            PRIMARY          1              o_orderkey      1500000       BTREE

orders     1            orders_fk1       1              o_custkey       100000        BTREE

orders     1            orders_dt_idx    1              o_orderdate     2407          BTREE

                                                                                      Index_
Table z    Non_unique   Key_name         Seq_in_index   Column_name     Cardinality
                                                                                      type
customer   0            PRIMARY          1              c_custkey       150000        BTREE

customer   1            customer_fk1     1              c_nationkey     25            BTREE
MySQL执行计划
     explain select * from lineitem where l_orderkey=3 and l_shipdate='1994-01-16';

id   select_type   table      type   possible_keys   key       key_len   ref     rows   Extra
                                     PRIMARY,                                           Using
1    SIMPLE        lineitem   ref                    PRIMARY   4         const   8
                                     li_shp_dt_idx                                      where



     ▪ 执行计划
          ▫   MySQL通过查询优化器对Query涉及的表的相关统计信息进行分析,得到一个认
              为最合理最优化的数据数据访问方式,也就是常说的“执行计划”。

          ▫   通过执行计划可以知道什么时候必须为表建立索引以得到一个使用索引来查询记录
              的更快的select,优化器是否以一个最佳次序连接表。
MySQL执行计划
     explain select * from lineitem where l_orderkey=3 and l_shipdate='1994-01-16';

id   select_type   table      type   possible_keys   key       key_len   ref     rows   Extra
                                     PRIMARY,                                           Using
1    SIMPLE        lineitem   ref                    PRIMARY   4         const   8
                                     li_shp_dt_idx                                      where



     ▪ 执行计划的语法

          ▪    EXPLAIN tbl_name; ---- DESCRIBE tbl_name;

          ▪    EXPLAIN [EXTENDED] SELECT select_options;
MySQL执行计划解析
id       select_type    table      type   possible_keys   key       key_len   ref     rows   Extra
                                          PRIMARY,                                           Using
1        SIMPLE         lineitem   ref                    PRIMARY   4         const   8
                                          li_shp_dt_idx                                      where



     ▫     id
            SELECT标识符
     ▫     table
            输出行所引用的表名

     ▫     possible_keys
            MySQL执行查询时可以使用的索引
     ▫     key         IMPORTANT

            MySQL优化器选择使用的索引,如果没有选择索引,值为NULL
MySQL执行计划解析
id       select_type    table      type   possible_keys   key       key_len   ref     rows   Extra
                                          PRIMARY,                                           Using
1        SIMPLE         lineitem   ref                    PRIMARY   4         const   8
                                          li_shp_dt_idx                                      where




     ▫     key_len
             MySQL决定使用的索引键长度
     ▫     ref
             列出是使用某个表的某个字段( join )or常量const来与key一起进行过滤
     ▫     rows        IMPORTANT
             MySQL查询优化器通过系统收集的统计信息估算的结果集记录行数
MySQL执行计划解析
id       select_type    table      type    possible_keys   key       key_len   ref     rows   Extra
                                           PRIMARY,                                           Using
1        SIMPLE         lineitem   ref                     PRIMARY   4         const   8
                                           li_shp_dt_idx                                      where



     ▫    select_type

            ▫   SIMPLE                    简单的SELECT,即不使用表连接或子查询

            ▫   PRIMARY                   主查询,子查询中最外层的查询,但并非一定是主键查询

            ▫   UNION                     UNION诧句中的第二个SELECT或之后的SELECT诧句

            ▫   DEPENDENT UNION           子查询UNION中第二个SELECT或之后的SELECT诧句,且依赖于外部查询结果集

            ▫   UNION RESULT              UNION的结果
MySQL执行计划解析
id   select_type   table      type   possible_keys   key       key_len   ref     rows   Extra
                                     PRIMARY,                                           Using
1    SIMPLE        lineitem   ref                    PRIMARY   4         const   8
                                     li_shp_dt_idx                                      where




        ▫   SUBQUERY                         子查询中的第一个SELECT,结果不依赖于外部查询结果集

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

        ▫   DERIVED                           用于导出表的SELECT诧句(FROM子句中的子查询)

        ▫   UNCACHEABLE SUBQUERY              UNION中第二个或之后的SELECT,不可被缓冲的子查询
Examples                                                               select *

                                                                        key_
id   select_type   table        type    possible_keys          key               ref     rows     Extra
                                                                        len
                                                                                                  Using
1    PRIMARY       customer     ALL     NULL                   NULL     NULL     NULL    150000
                                                                                                  where
     DEPENDENT
2                  orders       const   PRIMARY,orders_fk1     PK       4        const   1
     SUBQUERY
     DEPENDENT                                                                                    Using
3                  orders       range   PRIMARY,orders_fk1     PK       4        NULL    2
     UNION                                                                                        where
NU   UNION
LL
                   <union2,3>   ALL     NULL                   NULL     NULL     NULL    NULL
     RESULT

                                                                     id=2

explain select * from customer where c_custkey IN(select o_custkey from orders where
o_orderkey=1 UNION ALL select o_custkey from orders where o_orderkey IN (10,20) );

                                                        id=3
MySQL执行计划解析
id   select_type     table      type   possible_keys   key         key_len   ref     rows    Extra
                                       PRIMARY,                                              Using
1    SIMPLE          lineitem   ref                    PRIMARY     4         const   8
                                       li_shp_dt_idx                                         where



     ▫   type      IMPORTANT

          ▫     system
                 查询的表只有一行数据(系统表),const连接类型的一个特例
          ▫     const
                 至多只有一行匹配,在查询开始时被读取
                 const用于PRIMARY KEY(all)或UNIQUE索引和常数作比较
                 SELECT * FROM tbl_name WHERE primary_key=1;
                 SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2;
                 SELECT * FROM tbl_name WHERE unique_key=1;
Examples
id    select_type   table        type     possible_keys   key         key_len   ref    rows      Extra

1     PRIMARY       <derived2>   system   NULL            NULL        NULL      NULL   1
2     DERIVED       lineitem     const    PRIMARY         PRIMARY     8                1

    explain select * from (select * from lineitem where l_orderkey=3 and l_linenumber=2) test;


       <derived2>表示查询结果来自一个衍生表,其中2代表该
       查询衍生自第二个select查询,即id为2的select。
                                                                PRIMARY KEY


         TIPS:
         INDEX:普通索引
         UNIQUE INDEX:唯一性索引,对于每个索引键,表中只有一条记录与之匹配
         PRIMARY KEY:主键索引,隐含UNIQUE,NOT NULL
MySQL执行计划解析
▫   eq_ref
      对于前表的行组合,仅从该表中读取一行。它用在一个索引的所有部分都被连接所使用,并且索引
      是UNIQUE NOT NULL或PRIMARY KEY。--唯一性索引扫描
      SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
      SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column
          AND ref_table.key_column_part2=1;
▫   ref
      对于前表的行组合,所有有配索引值的行将从该表中读取。如果连接不能基于关键字选择单个行,
      则使用ref。--非唯一性索引扫描
      SELECT * FROM ref_table WHERE key_column=expr;
      SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column;
      SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column;
Examples
                                                                                                      Ext
id    select_type   table      type     possible_keys   key        key_len   ref            rows
                                                                                                      ra
1     SIMPLE        orders     ALL      orders_fk1      NULL       NULL      NULL           1500000
                                                                             tpch.orders.
1     SIMPLE        customer   eq_ref   PRIMARY         PRIMARY    4                        1
                                                                             o_custkey

     explain select * from customer,orders where customer.c_custkey=orders.o_custkey;


                                                              PRIMARY KEY


                内层循环优化,被驱动表的join字段被索引

           TIPS:MySQL中的JOIN算法都是用Nested Loop Join,即通过驱动表的结果集作为循环基础数
           据,然后将该结果集中的数据作为过滤条件一条条地到下一个表中查询数据,最后合并结果。
Examples
                                                                                                     Ext
id    select_type   table      type     possible_keys   key       key_len   ref            rows
                                                                                                     ra
1     SIMPLE        orders     ALL      PRIMARY         NULL      NULL      NULL           1500000
                                                                            tpch.orders.
1     SIMPLE        lineitem   ref      PRIMARY         PRIMARY   4                        4
                                                                            o_orderkey

    explain select * from orders,lineitem where lineitem.l_orderkey=orders.o_orderkey;
                                                                                                     Ext
id    select_type   table      type     possible_keys   key       key_len   ref            rows
                                                                                                     ra
1     SIMPLE        orders     ALL      PRIMARY         NULL      NULL      NULL           1500000
                                                                            tpch.orders.
1     SIMPLE        lineitem   eq_ref   PRIMARY         PRIMARY   8         o_orderkey,    1
                                                                            const
    explain select * from orders,lineitem where lineitem.l_orderkey=orders.o_orderkey
    and l_linenumber=2;
                                                        PRIMARY KEY_1
         PRIMARY KEY_2
MySQL执行计划解析
▫   fulltext
      进行全文索引扫描,仅MyISAM,仅CHAR、VARCHAR和TEXT三种数据类型可以建立。
▫   ref_or_null
      类似ref,添加了NULL值的查询。在解决子查询中经常使用该连接类型的优化。
      SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL;
▫   index_merge
      索引合并优化,使用两个或多个索引,然后对索引结果进行合并,再读取表数据。
Examples
id    select_type   table      type     possible_keys    key              key_len   ref    rows   Extra

                                                                                                  Using
                               index_   li_shp_dt_idx,   li_shp_dt_idx,                           intersect(li_shp_dt_
1     SIMPLE        lineitem                                              3,3       NULL   1
                               merge    li_com_dt_idx    li_com_dt_idx                            idx,li_com_dt_idx);
                                                                                                  Usingwhere


     explain select * from lineitem where l_commitdate='1996-02-12' and
     l_shipdate='1996_02_12';
MySQL执行计划解析
▫   unique_subquery
     子查询中的返回结果字段组合是主键或唯一约束
     value IN (SELECT primary_key FROM single_table WHERE some_expr)
▫   index_subquery
     子查询中的返回结果字段组合是一个索引,为非唯一索引
     value IN (SELECT key_column FROM single_table WHERE some_expr)
▫   range
     索引范围扫描
     SELECT * FROM tbl_name WHERE key_column = 10;
     SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20;
     SELECT * FROM tbl_name WHERE key_column IN (10,20,30);
     SELECT * FROM tbl_name WHERE key_part1= 10 AND key_part2 IN (10,20,30);
MySQL执行计划解析
                                            ATTENTION
▫   index-- Full Index Scan
     全索引扫描,比ALL快,因为索引文件通常比数据文件小。当查询的列属于某个索引的一部分时,
     使用该种索引。
▫   ALL-- Full Table Scan
     全表扫描,特别注意。
Examples
id   select_type    table      type    possible_keys   key       key_len   ref    rows      Extra
                                                                                            Using
1    SIMPLE         lineitem   index   NULL            PRIMARY   8         NULL   6001215
                                                                                            index


     explain select l_orderkey from lineitem;


id    select_type   table      type    possible_keys   key       key_len   ref    rows      Extra
                                                                                            Using
1     SIMPLE        lineitem   ALL     NULL            NULL      NULL      NULL   6001215
                                                                                            where

     explain select * from lineitem where l_linestatus='F';
MySQL执行计划解析
id   select_type    table        type   possible_keys   key       key_len   ref     rows   Extra
                                        PRIMARY,                                           Using
1    SIMPLE         lineitem     ref                    PRIMARY   4         const   8
                                        li_shp_dt_idx                                      where



                      IMPORTANT
     ▫   Extra
               MySQL解决查询的额外详细信息。注意using filesort和using temporary。
           ▫    Using filesort
                   当Query中包含ORDER BY操作,且无法利用索引完成排序操作的时候,MySQL查询
                   优化器不得不选择相应的排序算法来实现。MySQL需要额外的一次传递,以找出如何
                   按排序顺序检索行。通过根据连接类型浏览所有行并为所有匹配WHERE子句的行保存
                   排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行
           ▫    Using temporary
                   为了解决某些查询,MySQL需要创建一个临时表来存放结果
                   典型情冴如查询包含可以按不同情冴列出的GROUP BY和ORDER BY子句
MySQL执行计划解析
▫   Using where
      如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则出现该信息。
▫   Using index
      只访问索引,不读取表获取数据。覆盖索引。
▫   Using join buffer
      当join类型为ALL、index、range或index_merge时使用。
▫   Distinct
      查找distinct值,当MySQL找到第1个匹配行后,停止为当前的行组合搜索更多的行。
MySQL执行计划解析
▫   Impossible WHERE noticed after reading const tables
      MySQL 已经读了const(或system)表,并发现WHERE子句false。
▫   No tables used
      查询没有FROM子句,或有双重FROM子句。
▫   Using index for group-by
      MySQL查询优化器使用松散索引扫描实现GROUP BY或DISTINCT,即完全利用索引扫描
      来实现GROUP BY,不需要扫描所有满足条件的索引键即可完成操作。
▫   Full scan on NULL key
      子查询优化时,优化器无法使用索引查找时的后备方案。
▫   Range checked for each record (index map:N)
      MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索
      引可以使用。对前面的表的每个行组合,MySQL检查是否可以使用range或index_merge访
      问方法来索取行。
▫   ……
Examples
                                                            key_
id   select_type   table      type   possible_keys   key           ref            rows      Extra
                                                            len
                                                                                            Using
                                                                                            where ;
                                                                                            Using
1    PRIMARY       orders     ALL    orders_dt_idx   NULL   NULL   NULL           1498108
                                                                                            temporary;
                                                                                            Using
                                                                                            filesort
                                                                                            Using
     DEPENDENT
2                  lineitem   ref    PRIMARY         PK     4      tpch.orders.   4         where
     SUBQUERY
                                                                   o_orderkey

     explain select * from orders where o_orderdate >= date ' 1993-07-01 '
     and exists( select *
     from lineitem
     where l_orderkey = o_orderkey
     and l_commitdate < l_receiptdate )
     group by o_orderpriority
     order by o_orderpriority;
Examples
                                                                      key_
id   select_type   table      type    possible_keys   key                    ref    rows   Extra
                                                                      len
                                                                                           Using index
1    SIMPLE        lineitem   range   NULL            li_shp_dt_idx   3      NULL   2526
                                                                                           for group-by


        explain select distinct l_shipdate from lineitem;
MySQL EXPLAIN局限
▫   EXPLAIN的部分统计信息为估算值;

▫   EXPLAIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划;

▫   EXPLAIN看不到关于触发器、存储过程的信息或用户自定义函数对查询的影响情冴;

▫   EXPLAIN不能显示MySQL在执行查询时所作的优化工作;

▫   EXPLAIN对于子查询并不一定能找到最优的执行计划;

▫   EXPLAIN选择的存储引擎不同,对执行计划有影响。
Q&A


THANK YOU!

More Related Content

Viewers also liked

Sql常见面试题
Sql常见面试题Sql常见面试题
Sql常见面试题
yiditushe
 
可视化与可视分析从数据拥有者到数据用户的桥梁
可视化与可视分析从数据拥有者到数据用户的桥梁可视化与可视分析从数据拥有者到数据用户的桥梁
可视化与可视分析从数据拥有者到数据用户的桥梁
gettyying
 
下一代推荐引擎的关键技术及应用案例
下一代推荐引擎的关键技术及应用案例下一代推荐引擎的关键技术及应用案例
下一代推荐引擎的关键技术及应用案例
gettyying
 
Oracle面市笔记
Oracle面市笔记Oracle面市笔记
Oracle面市笔记
yiditushe
 
数据挖掘竞赛经验分享 严强
数据挖掘竞赛经验分享 严强数据挖掘竞赛经验分享 严强
数据挖掘竞赛经验分享 严强
Felicia Wenyi Fei
 

Viewers also liked (20)

不生病的理由
不生病的理由不生病的理由
不生病的理由
 
Sql常见面试题
Sql常见面试题Sql常见面试题
Sql常见面试题
 
用户研究中的数据分析
用户研究中的数据分析用户研究中的数据分析
用户研究中的数据分析
 
可视化与可视分析从数据拥有者到数据用户的桥梁
可视化与可视分析从数据拥有者到数据用户的桥梁可视化与可视分析从数据拥有者到数据用户的桥梁
可视化与可视分析从数据拥有者到数据用户的桥梁
 
下一代推荐引擎的关键技术及应用案例
下一代推荐引擎的关键技术及应用案例下一代推荐引擎的关键技术及应用案例
下一代推荐引擎的关键技术及应用案例
 
在线卡片分类测试和数据分析工具分享
在线卡片分类测试和数据分析工具分享在线卡片分类测试和数据分析工具分享
在线卡片分类测试和数据分析工具分享
 
Some experiences and lessons learnt from hunting a job
Some experiences and lessons learnt from hunting a jobSome experiences and lessons learnt from hunting a job
Some experiences and lessons learnt from hunting a job
 
Twitter 数据分析
Twitter 数据分析Twitter 数据分析
Twitter 数据分析
 
Oracle面市笔记
Oracle面市笔记Oracle面市笔记
Oracle面市笔记
 
Banking Big Data Analytics
Banking Big Data AnalyticsBanking Big Data Analytics
Banking Big Data Analytics
 
Oracle数据库分析函数详解
Oracle数据库分析函数详解Oracle数据库分析函数详解
Oracle数据库分析函数详解
 
The Joys of Clean Data with Matt Dowle
The Joys of Clean Data with Matt DowleThe Joys of Clean Data with Matt Dowle
The Joys of Clean Data with Matt Dowle
 
The simplethebeautiful
The simplethebeautifulThe simplethebeautiful
The simplethebeautiful
 
面试常见问题
面试常见问题面试常见问题
面试常见问题
 
数据挖掘竞赛经验分享 严强
数据挖掘竞赛经验分享 严强数据挖掘竞赛经验分享 严强
数据挖掘竞赛经验分享 严强
 
网站分析及数据推动设计决策分享- Smartdesign Shanghai Taylor
网站分析及数据推动设计决策分享- Smartdesign Shanghai Taylor网站分析及数据推动设计决策分享- Smartdesign Shanghai Taylor
网站分析及数据推动设计决策分享- Smartdesign Shanghai Taylor
 
Market Timing, Big Data, and Machine Learning by Xiao Qiao at QuantCon 2016
Market Timing, Big Data, and Machine Learning by Xiao Qiao at QuantCon 2016Market Timing, Big Data, and Machine Learning by Xiao Qiao at QuantCon 2016
Market Timing, Big Data, and Machine Learning by Xiao Qiao at QuantCon 2016
 
Big Data Alchemy: How can Banks Maximize the Value of their Customer Data?
Big Data Alchemy: How can Banks Maximize the Value of their Customer Data?Big Data Alchemy: How can Banks Maximize the Value of their Customer Data?
Big Data Alchemy: How can Banks Maximize the Value of their Customer Data?
 
Working With Big Data
Working With Big DataWorking With Big Data
Working With Big Data
 
Visual Design with Data
Visual Design with DataVisual Design with Data
Visual Design with Data
 

Similar to MySQL_EXPLAIN_liling (9)

My sql explain & select
My sql explain & selectMy sql explain & select
My sql explain & select
 
Sql Server 高级技巧系列之三整体优化
Sql Server 高级技巧系列之三整体优化Sql Server 高级技巧系列之三整体优化
Sql Server 高级技巧系列之三整体优化
 
MySQL查询优化浅析
MySQL查询优化浅析MySQL查询优化浅析
MySQL查询优化浅析
 
Mysql数据库开发的三十六条军规 石展_完整
Mysql数据库开发的三十六条军规 石展_完整Mysql数据库开发的三十六条军规 石展_完整
Mysql数据库开发的三十六条军规 石展_完整
 
My sql数据库开发的三十六条军规
My sql数据库开发的三十六条军规My sql数据库开发的三十六条军规
My sql数据库开发的三十六条军规
 
MySQL数据库开发的三十六条军规
MySQL数据库开发的三十六条军规MySQL数据库开发的三十六条军规
MySQL数据库开发的三十六条军规
 
MySQL Base Skill
MySQL Base SkillMySQL Base Skill
MySQL Base Skill
 
Mysql fast share
Mysql fast shareMysql fast share
Mysql fast share
 
MySQL入門介紹
MySQL入門介紹MySQL入門介紹
MySQL入門介紹
 

MySQL_EXPLAIN_liling

  • 1. MySQL EXPLAIN 李 玲 2011年8月
  • 3. 测试环境数据TPC-H • TPC-H是决策支持数据库的基准测试,它包含了一整套面向商业的ad-hoc查询和并发数据修改,强 调测试的是数据库、平台和I/O性能,关注查询能力。
  • 4. show index from lineitem & orders & customer Index_ Table Non_unique Key_name Seq_in_index Column_name Cardinality type lineitem 0 PRIMARY 1 l_orderkey 1500303 BTREE lineitem 0 PRIMARY 2 l_linenumber 6001215 BTREE lineitem 1 li_shp_dt_idx 1 l_shipdate 2525 BTREE lineitem 1 li_com_dt_idx 1 l_commitdate 2465 BTREE lineitem 1 li_rcpt_dt_idx 1 l_receiptdate 2553 BTREE Index_ Table Non_unique Key_name Seq_in_index Column_name Cardinality type orders 0 PRIMARY 1 o_orderkey 1500000 BTREE orders 1 orders_fk1 1 o_custkey 100000 BTREE orders 1 orders_dt_idx 1 o_orderdate 2407 BTREE Index_ Table z Non_unique Key_name Seq_in_index Column_name Cardinality type customer 0 PRIMARY 1 c_custkey 150000 BTREE customer 1 customer_fk1 1 c_nationkey 25 BTREE
  • 5. MySQL执行计划 explain select * from lineitem where l_orderkey=3 and l_shipdate='1994-01-16'; id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using 1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▪ 执行计划 ▫ MySQL通过查询优化器对Query涉及的表的相关统计信息进行分析,得到一个认 为最合理最优化的数据数据访问方式,也就是常说的“执行计划”。 ▫ 通过执行计划可以知道什么时候必须为表建立索引以得到一个使用索引来查询记录 的更快的select,优化器是否以一个最佳次序连接表。
  • 6. MySQL执行计划 explain select * from lineitem where l_orderkey=3 and l_shipdate='1994-01-16'; id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using 1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▪ 执行计划的语法 ▪ EXPLAIN tbl_name; ---- DESCRIBE tbl_name; ▪ EXPLAIN [EXTENDED] SELECT select_options;
  • 7. MySQL执行计划解析 id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using 1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▫ id SELECT标识符 ▫ table 输出行所引用的表名 ▫ possible_keys MySQL执行查询时可以使用的索引 ▫ key IMPORTANT MySQL优化器选择使用的索引,如果没有选择索引,值为NULL
  • 8. MySQL执行计划解析 id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using 1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▫ key_len MySQL决定使用的索引键长度 ▫ ref 列出是使用某个表的某个字段( join )or常量const来与key一起进行过滤 ▫ rows IMPORTANT MySQL查询优化器通过系统收集的统计信息估算的结果集记录行数
  • 9. MySQL执行计划解析 id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using 1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▫ select_type ▫ SIMPLE 简单的SELECT,即不使用表连接或子查询 ▫ PRIMARY 主查询,子查询中最外层的查询,但并非一定是主键查询 ▫ UNION UNION诧句中的第二个SELECT或之后的SELECT诧句 ▫ DEPENDENT UNION 子查询UNION中第二个SELECT或之后的SELECT诧句,且依赖于外部查询结果集 ▫ UNION RESULT UNION的结果
  • 10. MySQL执行计划解析 id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using 1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▫ SUBQUERY 子查询中的第一个SELECT,结果不依赖于外部查询结果集 ▫ DEPENDENT SUBQUERY 子查询中的第一个SELECT,依赖于外部查询结果集 ▫ DERIVED 用于导出表的SELECT诧句(FROM子句中的子查询) ▫ UNCACHEABLE SUBQUERY UNION中第二个或之后的SELECT,不可被缓冲的子查询
  • 11. Examples select * key_ id select_type table type possible_keys key ref rows Extra len Using 1 PRIMARY customer ALL NULL NULL NULL NULL 150000 where DEPENDENT 2 orders const PRIMARY,orders_fk1 PK 4 const 1 SUBQUERY DEPENDENT Using 3 orders range PRIMARY,orders_fk1 PK 4 NULL 2 UNION where NU UNION LL <union2,3> ALL NULL NULL NULL NULL NULL RESULT id=2 explain select * from customer where c_custkey IN(select o_custkey from orders where o_orderkey=1 UNION ALL select o_custkey from orders where o_orderkey IN (10,20) ); id=3
  • 12. MySQL执行计划解析 id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using 1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▫ type IMPORTANT ▫ system 查询的表只有一行数据(系统表),const连接类型的一个特例 ▫ const 至多只有一行匹配,在查询开始时被读取 const用于PRIMARY KEY(all)或UNIQUE索引和常数作比较 SELECT * FROM tbl_name WHERE primary_key=1; SELECT * FROM tbl_name WHERE primary_key_part1=1 AND primary_key_part2=2; SELECT * FROM tbl_name WHERE unique_key=1;
  • 13. Examples id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY <derived2> system NULL NULL NULL NULL 1 2 DERIVED lineitem const PRIMARY PRIMARY 8 1 explain select * from (select * from lineitem where l_orderkey=3 and l_linenumber=2) test; <derived2>表示查询结果来自一个衍生表,其中2代表该 查询衍生自第二个select查询,即id为2的select。 PRIMARY KEY TIPS: INDEX:普通索引 UNIQUE INDEX:唯一性索引,对于每个索引键,表中只有一条记录与之匹配 PRIMARY KEY:主键索引,隐含UNIQUE,NOT NULL
  • 14. MySQL执行计划解析 ▫ eq_ref 对于前表的行组合,仅从该表中读取一行。它用在一个索引的所有部分都被连接所使用,并且索引 是UNIQUE NOT NULL或PRIMARY KEY。--唯一性索引扫描 SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column; SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column AND ref_table.key_column_part2=1; ▫ ref 对于前表的行组合,所有有配索引值的行将从该表中读取。如果连接不能基于关键字选择单个行, 则使用ref。--非唯一性索引扫描 SELECT * FROM ref_table WHERE key_column=expr; SELECT * FROM ref_table,other_table WHERE ref_table.key_column=other_table.column; SELECT * FROM ref_table,other_table WHERE ref_table.key_column_part1=other_table.column;
  • 15. Examples Ext id select_type table type possible_keys key key_len ref rows ra 1 SIMPLE orders ALL orders_fk1 NULL NULL NULL 1500000 tpch.orders. 1 SIMPLE customer eq_ref PRIMARY PRIMARY 4 1 o_custkey explain select * from customer,orders where customer.c_custkey=orders.o_custkey; PRIMARY KEY 内层循环优化,被驱动表的join字段被索引 TIPS:MySQL中的JOIN算法都是用Nested Loop Join,即通过驱动表的结果集作为循环基础数 据,然后将该结果集中的数据作为过滤条件一条条地到下一个表中查询数据,最后合并结果。
  • 16. Examples Ext id select_type table type possible_keys key key_len ref rows ra 1 SIMPLE orders ALL PRIMARY NULL NULL NULL 1500000 tpch.orders. 1 SIMPLE lineitem ref PRIMARY PRIMARY 4 4 o_orderkey explain select * from orders,lineitem where lineitem.l_orderkey=orders.o_orderkey; Ext id select_type table type possible_keys key key_len ref rows ra 1 SIMPLE orders ALL PRIMARY NULL NULL NULL 1500000 tpch.orders. 1 SIMPLE lineitem eq_ref PRIMARY PRIMARY 8 o_orderkey, 1 const explain select * from orders,lineitem where lineitem.l_orderkey=orders.o_orderkey and l_linenumber=2; PRIMARY KEY_1 PRIMARY KEY_2
  • 17. MySQL执行计划解析 ▫ fulltext 进行全文索引扫描,仅MyISAM,仅CHAR、VARCHAR和TEXT三种数据类型可以建立。 ▫ ref_or_null 类似ref,添加了NULL值的查询。在解决子查询中经常使用该连接类型的优化。 SELECT * FROM ref_table WHERE key_column=expr OR key_column IS NULL; ▫ index_merge 索引合并优化,使用两个或多个索引,然后对索引结果进行合并,再读取表数据。
  • 18. Examples id select_type table type possible_keys key key_len ref rows Extra Using index_ li_shp_dt_idx, li_shp_dt_idx, intersect(li_shp_dt_ 1 SIMPLE lineitem 3,3 NULL 1 merge li_com_dt_idx li_com_dt_idx idx,li_com_dt_idx); Usingwhere explain select * from lineitem where l_commitdate='1996-02-12' and l_shipdate='1996_02_12';
  • 19. MySQL执行计划解析 ▫ unique_subquery 子查询中的返回结果字段组合是主键或唯一约束 value IN (SELECT primary_key FROM single_table WHERE some_expr) ▫ index_subquery 子查询中的返回结果字段组合是一个索引,为非唯一索引 value IN (SELECT key_column FROM single_table WHERE some_expr) ▫ range 索引范围扫描 SELECT * FROM tbl_name WHERE key_column = 10; SELECT * FROM tbl_name WHERE key_column BETWEEN 10 and 20; SELECT * FROM tbl_name WHERE key_column IN (10,20,30); SELECT * FROM tbl_name WHERE key_part1= 10 AND key_part2 IN (10,20,30);
  • 20. MySQL执行计划解析 ATTENTION ▫ index-- Full Index Scan 全索引扫描,比ALL快,因为索引文件通常比数据文件小。当查询的列属于某个索引的一部分时, 使用该种索引。 ▫ ALL-- Full Table Scan 全表扫描,特别注意。
  • 21. Examples id select_type table type possible_keys key key_len ref rows Extra Using 1 SIMPLE lineitem index NULL PRIMARY 8 NULL 6001215 index explain select l_orderkey from lineitem; id select_type table type possible_keys key key_len ref rows Extra Using 1 SIMPLE lineitem ALL NULL NULL NULL NULL 6001215 where explain select * from lineitem where l_linestatus='F';
  • 22. MySQL执行计划解析 id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using 1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where IMPORTANT ▫ Extra MySQL解决查询的额外详细信息。注意using filesort和using temporary。 ▫ Using filesort 当Query中包含ORDER BY操作,且无法利用索引完成排序操作的时候,MySQL查询 优化器不得不选择相应的排序算法来实现。MySQL需要额外的一次传递,以找出如何 按排序顺序检索行。通过根据连接类型浏览所有行并为所有匹配WHERE子句的行保存 排序关键字和行的指针来完成排序。然后关键字被排序,并按排序顺序检索行 ▫ Using temporary 为了解决某些查询,MySQL需要创建一个临时表来存放结果 典型情冴如查询包含可以按不同情冴列出的GROUP BY和ORDER BY子句
  • 23. MySQL执行计划解析 ▫ Using where 如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则出现该信息。 ▫ Using index 只访问索引,不读取表获取数据。覆盖索引。 ▫ Using join buffer 当join类型为ALL、index、range或index_merge时使用。 ▫ Distinct 查找distinct值,当MySQL找到第1个匹配行后,停止为当前的行组合搜索更多的行。
  • 24. MySQL执行计划解析 ▫ Impossible WHERE noticed after reading const tables MySQL 已经读了const(或system)表,并发现WHERE子句false。 ▫ No tables used 查询没有FROM子句,或有双重FROM子句。 ▫ Using index for group-by MySQL查询优化器使用松散索引扫描实现GROUP BY或DISTINCT,即完全利用索引扫描 来实现GROUP BY,不需要扫描所有满足条件的索引键即可完成操作。 ▫ Full scan on NULL key 子查询优化时,优化器无法使用索引查找时的后备方案。 ▫ Range checked for each record (index map:N) MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索 引可以使用。对前面的表的每个行组合,MySQL检查是否可以使用range或index_merge访 问方法来索取行。 ▫ ……
  • 25. Examples key_ id select_type table type possible_keys key ref rows Extra len Using where ; Using 1 PRIMARY orders ALL orders_dt_idx NULL NULL NULL 1498108 temporary; Using filesort Using DEPENDENT 2 lineitem ref PRIMARY PK 4 tpch.orders. 4 where SUBQUERY o_orderkey explain select * from orders where o_orderdate >= date ' 1993-07-01 ' and exists( select * from lineitem where l_orderkey = o_orderkey and l_commitdate < l_receiptdate ) group by o_orderpriority order by o_orderpriority;
  • 26. Examples key_ id select_type table type possible_keys key ref rows Extra len Using index 1 SIMPLE lineitem range NULL li_shp_dt_idx 3 NULL 2526 for group-by explain select distinct l_shipdate from lineitem;
  • 27. MySQL EXPLAIN局限 ▫ EXPLAIN的部分统计信息为估算值; ▫ EXPLAIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划; ▫ EXPLAIN看不到关于触发器、存储过程的信息或用户自定义函数对查询的影响情冴; ▫ EXPLAIN不能显示MySQL在执行查询时所作的优化工作; ▫ EXPLAIN对于子查询并不一定能找到最优的执行计划; ▫ EXPLAIN选择的存储引擎不同,对执行计划有影响。