如何通过使用MySQL的EXPLAIN命令来优化查询执行计划?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1841个文字,预计阅读时间需要8分钟。
使用 `explain` 关键字可以模拟优化器执行 SQL 查询语句,从而了解 MySQL 如何处理你的 SQL 语句。通过分析 `explain` 输出的信息,你可以知道查询的性能瓶颈。
1. `explain` 执行计划包含的信息: - 其中最重要的字段为类型,它表示连接类型,对查询性能影响最大。常见的类型有: - `ALL`:全表扫描,性能较差。 - `index`:使用索引,性能较好。 - `range`:范围查询,使用索引范围扫描。 - `ref`:非索引列与索引列的关联查询。 - `eq_ref`:类似于 ref,但用于多列索引或主键。 - `const`:常量引用,用于主键或唯一索引。 - `null`:无匹配行。
- 其中最重要的字段为:id、type、key、rows、Extra
- SIMPLE:简单的select查询,查询中不包含子查询或者union
- PRIMARY:查询中包含任何复杂的子部分,最外层查询则被标记为primary
- SUBQUERY:在select 或 where列表中包含了子查询
- DERIVED:在from列表中包含的子查询被标记为derived(衍生),mysql或递归执行这些子查询,把结果放在临时表里
- UNION:若第二个select出现在union之后,则被标记为union;若union包含在from子句的子查询中,外层select将被标记为derived
- UNION RESULT:从union表获取结果的select
- 使用临时表保存中间结果,也就是说mysql在对查询结果排序时使用了临时表,常见于order by 和 group by
- 表示相应的select操作中使用了覆盖索引(Covering Index),避免了访问表的数据行,效率高
- 如果同时出现Using where,表明索引被用来执行索引键值的查找(参考上图)
- 如果没用同时出现Using where,表明索引用来读取数据而非执行查找动作
- 覆盖索引(Covering Index):也叫索引覆盖。就是select列表中的字段,只用从索引中就能获取,不必根据索引再次读取数据文件,换句话说查询列要被所建的索引覆盖。
- 注意:
- a、如需使用覆盖索引,select列表中的字段只取出需要的列,不要使用select *
- b、如果将所有字段都建索引会导致索引文件过大,反而降低crud性能
- 使用了where过滤
- 使用了链接缓存
- where子句的值总是false,不能用来获取任何元祖
- 在没有group by子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段在进行计算,查询执行计划生成的阶段即可完成优化
- 优化distinct操作,在找到第一个匹配的元祖后即停止找同样值得动作
- 1(id = 4)、:select_type 为union,说明id=4的select是union里面的第二个select。
- 2(id = 3)、:因为是在from语句中包含的子查询所以被标记为DERIVED(衍生),where address = ‘11’ 通过复合索引idx_name_email_address就能检索到,所以type为index。
- 3(id = 2)、:因为是在select中包含的子查询所以被标记为SUBQUERY。
- 4(id = 1)、:select_type为PRIMARY表示该查询为最外层查询,table列被标记为 “derived3”表示查询结果来自于一个衍生表(id = 3 的select结果)。
- 5(id = NULL)、:代表从union的临时表中读取行的阶段,table列的 “union 1, 4”表示用id=1 和 id=4 的select结果进行union操作。
本文共计1841个文字,预计阅读时间需要8分钟。
使用 `explain` 关键字可以模拟优化器执行 SQL 查询语句,从而了解 MySQL 如何处理你的 SQL 语句。通过分析 `explain` 输出的信息,你可以知道查询的性能瓶颈。
1. `explain` 执行计划包含的信息: - 其中最重要的字段为类型,它表示连接类型,对查询性能影响最大。常见的类型有: - `ALL`:全表扫描,性能较差。 - `index`:使用索引,性能较好。 - `range`:范围查询,使用索引范围扫描。 - `ref`:非索引列与索引列的关联查询。 - `eq_ref`:类似于 ref,但用于多列索引或主键。 - `const`:常量引用,用于主键或唯一索引。 - `null`:无匹配行。
- 其中最重要的字段为:id、type、key、rows、Extra
- SIMPLE:简单的select查询,查询中不包含子查询或者union
- PRIMARY:查询中包含任何复杂的子部分,最外层查询则被标记为primary
- SUBQUERY:在select 或 where列表中包含了子查询
- DERIVED:在from列表中包含的子查询被标记为derived(衍生),mysql或递归执行这些子查询,把结果放在临时表里
- UNION:若第二个select出现在union之后,则被标记为union;若union包含在from子句的子查询中,外层select将被标记为derived
- UNION RESULT:从union表获取结果的select
- 使用临时表保存中间结果,也就是说mysql在对查询结果排序时使用了临时表,常见于order by 和 group by
- 表示相应的select操作中使用了覆盖索引(Covering Index),避免了访问表的数据行,效率高
- 如果同时出现Using where,表明索引被用来执行索引键值的查找(参考上图)
- 如果没用同时出现Using where,表明索引用来读取数据而非执行查找动作
- 覆盖索引(Covering Index):也叫索引覆盖。就是select列表中的字段,只用从索引中就能获取,不必根据索引再次读取数据文件,换句话说查询列要被所建的索引覆盖。
- 注意:
- a、如需使用覆盖索引,select列表中的字段只取出需要的列,不要使用select *
- b、如果将所有字段都建索引会导致索引文件过大,反而降低crud性能
- 使用了where过滤
- 使用了链接缓存
- where子句的值总是false,不能用来获取任何元祖
- 在没有group by子句的情况下,基于索引优化MIN/MAX操作或者对于MyISAM存储引擎优化COUNT(*)操作,不必等到执行阶段在进行计算,查询执行计划生成的阶段即可完成优化
- 优化distinct操作,在找到第一个匹配的元祖后即停止找同样值得动作
- 1(id = 4)、:select_type 为union,说明id=4的select是union里面的第二个select。
- 2(id = 3)、:因为是在from语句中包含的子查询所以被标记为DERIVED(衍生),where address = ‘11’ 通过复合索引idx_name_email_address就能检索到,所以type为index。
- 3(id = 2)、:因为是在select中包含的子查询所以被标记为SUBQUERY。
- 4(id = 1)、:select_type为PRIMARY表示该查询为最外层查询,table列被标记为 “derived3”表示查询结果来自于一个衍生表(id = 3 的select结果)。
- 5(id = NULL)、:代表从union的临时表中读取行的阶段,table列的 “union 1, 4”表示用id=1 和 id=4 的select结果进行union操作。

