MySQL_EXPLAIN_liling

1,895 views

Published on

Published in: Technology, Business
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,895
On SlideShare
0
From Embeds
0
Number of Embeds
217
Actions
Shares
0
Downloads
70
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

MySQL_EXPLAIN_liling

  1. 1. MySQLEXPLAIN 李 玲 2011年8月
  2. 2. Content测试环境数据MySQL执行计划MySQL执行计划解析Q&A
  3. 3. 测试环境数据TPC-H• TPC-H是决策支持数据库的基准测试,它包含了一整套面向商业的ad-hoc查询和并发数据修改,强 调测试的是数据库、平台和I/O性能,关注查询能力。
  4. 4. show index from lineitem & orders & customer Index_Table Non_unique Key_name Seq_in_index Column_name Cardinality typelineitem 0 PRIMARY 1 l_orderkey 1500303 BTREElineitem 0 PRIMARY 2 l_linenumber 6001215 BTREElineitem 1 li_shp_dt_idx 1 l_shipdate 2525 BTREElineitem 1 li_com_dt_idx 1 l_commitdate 2465 BTREElineitem 1 li_rcpt_dt_idx 1 l_receiptdate 2553 BTREE Index_Table Non_unique Key_name Seq_in_index Column_name Cardinality typeorders 0 PRIMARY 1 o_orderkey 1500000 BTREEorders 1 orders_fk1 1 o_custkey 100000 BTREEorders 1 orders_dt_idx 1 o_orderdate 2407 BTREE Index_Table z Non_unique Key_name Seq_in_index Column_name Cardinality typecustomer 0 PRIMARY 1 c_custkey 150000 BTREEcustomer 1 customer_fk1 1 c_nationkey 25 BTREE
  5. 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, Using1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▪ 执行计划 ▫ MySQL通过查询优化器对Query涉及的表的相关统计信息进行分析,得到一个认 为最合理最优化的数据数据访问方式,也就是常说的“执行计划”。 ▫ 通过执行计划可以知道什么时候必须为表建立索引以得到一个使用索引来查询记录 的更快的select,优化器是否以一个最佳次序连接表。
  6. 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, Using1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▪ 执行计划的语法 ▪ EXPLAIN tbl_name; ---- DESCRIBE tbl_name; ▪ EXPLAIN [EXTENDED] SELECT select_options;
  7. 7. MySQL执行计划解析id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▫ id SELECT标识符 ▫ table 输出行所引用的表名 ▫ possible_keys MySQL执行查询时可以使用的索引 ▫ key IMPORTANT MySQL优化器选择使用的索引,如果没有选择索引,值为NULL
  8. 8. MySQL执行计划解析id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using1 SIMPLE lineitem ref PRIMARY 4 const 8 li_shp_dt_idx where ▫ key_len MySQL决定使用的索引键长度 ▫ ref 列出是使用某个表的某个字段( join )or常量const来与key一起进行过滤 ▫ rows IMPORTANT MySQL查询优化器通过系统收集的统计信息估算的结果集记录行数
  9. 9. MySQL执行计划解析id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using1 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. 10. MySQL执行计划解析id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using1 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. 11. Examples select * key_id select_type table type possible_keys key ref rows Extra len Using1 PRIMARY customer ALL NULL NULL NULL NULL 150000 where DEPENDENT2 orders const PRIMARY,orders_fk1 PK 4 const 1 SUBQUERY DEPENDENT Using3 orders range PRIMARY,orders_fk1 PK 4 NULL 2 UNION whereNU UNIONLL <union2,3> ALL NULL NULL NULL NULL NULL RESULT id=2explain select * from customer where c_custkey IN(select o_custkey from orders whereo_orderkey=1 UNION ALL select o_custkey from orders where o_orderkey IN (10,20) ); id=3
  12. 12. MySQL执行计划解析id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using1 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. 13. Examplesid select_type table type possible_keys key key_len ref rows Extra1 PRIMARY <derived2> system NULL NULL NULL NULL 12 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. 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. 15. Examples Extid select_type table type possible_keys key key_len ref rows ra1 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. 16. Examples Extid select_type table type possible_keys key key_len ref rows ra1 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; Extid select_type table type possible_keys key key_len ref rows ra1 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. 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. 18. Examplesid 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. 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. 20. MySQL执行计划解析 ATTENTION▫ index-- Full Index Scan 全索引扫描,比ALL快,因为索引文件通常比数据文件小。当查询的列属于某个索引的一部分时, 使用该种索引。▫ ALL-- Full Table Scan 全表扫描,特别注意。
  21. 21. Examplesid select_type table type possible_keys key key_len ref rows Extra Using1 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 Using1 SIMPLE lineitem ALL NULL NULL NULL NULL 6001215 where explain select * from lineitem where l_linestatus=F;
  22. 22. MySQL执行计划解析id select_type table type possible_keys key key_len ref rows Extra PRIMARY, Using1 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. 23. MySQL执行计划解析▫ Using where 如果不读取表的所有数据,或不是仅仅通过索引就可以获取所有需要的数据,则出现该信息。▫ Using index 只访问索引,不读取表获取数据。覆盖索引。▫ Using join buffer 当join类型为ALL、index、range或index_merge时使用。▫ Distinct 查找distinct值,当MySQL找到第1个匹配行后,停止为当前的行组合搜索更多的行。
  24. 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. 25. Examples key_id select_type table type possible_keys key ref rows Extra len Using where ; Using1 PRIMARY orders ALL orders_dt_idx NULL NULL NULL 1498108 temporary; Using filesort Using DEPENDENT2 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. 26. Examples key_id select_type table type possible_keys key ref rows Extra len Using index1 SIMPLE lineitem range NULL li_shp_dt_idx 3 NULL 2526 for group-by explain select distinct l_shipdate from lineitem;
  27. 27. MySQL EXPLAIN局限▫ EXPLAIN的部分统计信息为估算值;▫ EXPLAIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划;▫ EXPLAIN看不到关于触发器、存储过程的信息或用户自定义函数对查询的影响情冴;▫ EXPLAIN不能显示MySQL在执行查询时所作的优化工作;▫ EXPLAIN对于子查询并不一定能找到最优的执行计划;▫ EXPLAIN选择的存储引擎不同,对执行计划有影响。
  28. 28. Q&ATHANK YOU!

×