MySQL执行计划

如何看懂执行计划

在MySQL中,执行计划(也称为Explain计划)是一个工具,它用于解释MySQL执行特定查询时的数据检索方法。执行计划可以展示MySQL是如何使用索引,是如何进行表连接,以及使用了哪些优化方法。这对于查询性能调优非常重要,因为它可以帮助发现性能瓶颈并优化查询。

以下是如何获取MySQL查询的执行计划的基本步骤:

执行带有EXPLAIN关键字的查询。你只需将EXPLAIN放在要分析的查询语句前面即可。例如:

   EXPLAIN SELECT * FROM your_table WHERE your_column = 'some_value';

id:select子句或表执行顺序,id相同,从上到下执行,id不同,id值越大,执行优先级越高。

select_type:查询的类型

  • SIMPLE:简单的select查询,查询中不包含子查询或union查询。
  • PRIMARY:查询中若包含任何复杂的子部分,最外层查询为PRIMARY,也就是最后加载的就是PRIMARY。
  • SUBQUERY:在select或where列表中包含了子查询,就为被标记为SUBQUERY。
  • DERIVED:在from列表中包含的子查询会被标记为DERIVED(衍生),MySQL会递归执行这些子查询,将结果放在临时表中。
  • UNION:若第二个select出现在union后,则被标记为UNION,若union包含在from子句的子查询中,外层select将被标记为DERIVED。
  • UNION RESULT:从union表获取结果的select。

table:显示sql操作属于哪张表的。

partitions:匹配的分区,值为NULL表示表未被分区。

type:对表访问方式,表示MySQL在表中找到所需行的方式,又称"访问类型"。

  • ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
  • index:Full Index Scan,index与ALL区别为index类型只遍历索引树
  • range:只检索给定范围的行,使用一个索引来选择行
  • ref_or_null:这种连接类型类似于ref,但是MySQL会额外搜索包含NULL值的行。此联接类型优化最常用于解析子查询
  • fulltext:使用fulltext索引执行连接。
  • ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
  • eq_ref:类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,就是多表连接中使用primary key或者 unique key作为关联条件
  • const:当MySQL对查询某部分进行优化,并转换为一个常量时,使用这些类型访问。如将主键置于where列表中,MySQL就能将该查询转换为一个常量,
  • system:system是const类型的特例,当查询的表只有一行的情况下。

possible_keys:显示可能应用在表中的索引,可能一个或多个。查询涉及到的字段若存在索引,则该索引将被列出,但不一定被查询实际使用。

Key:key列显示MySQL实际决定使用的键(索引),必然包含在possible_keys中,如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)

ref:关联的字段,常量等值查询,显示为const,如果为连接查询,显示关联的字段。

rows:MySQL估计为了执行查询而必须检查的行数

Extra:显示十分重要的额外信息。

  • Using filesort:表明mysql会对数据使用一个外部的索引排序,而不是按照表内的索引顺序进行读取。mysql中无法利用索引完成的排序操作称为"文件排序"。出现Using filesort就非常危险了,在数据量非常大的时候几乎"九死一生"。出现Using filesort尽快优化sql语句。
  • Using temporary:使用了临时表保存中间结果,常见于排序order by和分组查询group by。非常危险,"十死无生",急需优化。
  • Using index:表明相应的select操作中使用了覆盖索引,避免访问表的额外数据行,效率不错。

根据执行计划来优化查询性能

  1. 添加或调整索引:EXPLAIN命令返回的结果中的key列显示了MySQL在查询中实际使用的索引,possible_keys列显示了本次查询可能使用的全部索引。您可以根据这两列了解索引的使用情况。如果发现查询没有使用索引(type列显示为ALLindex),或者使用了全字段的索引(key_len列的长度很长),那么可能需要添加新的索引或者调整现有的索引。

  2. 修改查询结构:对查询进行部分修改,比如改变连接顺序,使用或不使用子查询,可以改善查询性能。例如,「IN (子查询)」这样的查询结构通常可以被改写为JOIN查询,以获得更好的性能。

  3. 调整查询条件:查询的WHERE条件可能会影响到索引的使用,过于复杂的查询条件或者对列进行函数处理(比如WHERE DATE(datetime) = '2022-01-01')可能会导致索引失效。调整WHERE条件,使其尽可能利用索引,可以提高查询性能。

  4. 优化数据方式:比如对于字符串类型,选择合适的字符集和整理顺序(Collation)有助于提高查询效率。同时,也可以通过改变存储引擎改善查询和写入性能。

  5. 使用分区:对大表进行分区,可以根据查询条件只读取部分分区的数据,从而提高查询性能。

相关推荐
小光学长2 分钟前
基于vue框架的的流浪宠物救助系统25128(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
数据库·vue.js·宠物
掘金-我是哪吒2 分钟前
微服务mysql,redis,elasticsearch, kibana,cassandra,mongodb, kafka
redis·mysql·mongodb·elasticsearch·微服务
零炻大礼包1 小时前
【SQL server】数据库远程连接配置
数据库
zmgst1 小时前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
令狐少侠20111 小时前
explain执行计划分析 ref_
mysql
随心............1 小时前
python操作MySQL以及SQL综合案例
数据库·mysql
€☞扫地僧☜€1 小时前
docker 拉取MySQL8.0镜像以及安装
运维·数据库·docker·容器
CopyDragon1 小时前
设置域名跨越访问
数据库·sqlite
xjjeffery1 小时前
MySQL 基础
数据库·mysql
写bug的小屁孩1 小时前
前后端交互接口(三)
运维·服务器·数据库·windows·用户界面·qt6.3