概述
优化SQL,是DBA常见的工作之一。如何高效、快速地优化一条语句,是每个DBA经常要面对的一个问题。在日常的优化工作中,我发现有很多操作是在优化过程中必不可少的步骤。然而这些步骤重复性的执行,又会耗费DBA很多精力。
今天抽空总结下mysql数据库常见的一些优化步骤,仅供参考。
执行计划 — EXPLAIN命令
执行计划是语句优化的主要切入点,通过执行计划的判读了解语句的执行过程。在执行计划生成方面,MySQL与Oracle明显不同,它不会缓存执行计划,每次都执行“硬解析”。
1、基本用法
EXPLAIN QUERY
当在一个Select语句前使用关键字EXPLAIN时,MySQL会解释了即将如何运行该Select语句,它显示了表如何连接、连接的顺序等信息。
EXPLAIN EXTENDED QUERY
当使用EXTENDED关键字时,EXPLAIN产生附加信息,可以用SHOW WARNINGS浏览。该信息显示优化器限定SELECT语句中的表和列名,重写并且执行优化规则后SELECT语句是什么样子,并且还可能包括优化过程的其它注解。
EXPLAIN PARTITIONS QUERY
显示的是查询要访问的数据分片——如果有分片的话。它只能在MySQL5.1及更新的版本里使用。
EXPLAIN FORMAT=JSON (5.6新特性)
另一个格式显示执行计划。可以看到诸如表间关联方式等信息。
2、输出字段
下面说明一下EXPLAIN输出的字段含义:
id
MySQL选定的执行计划中查询的序列号。如果语句里没有子查询等情况,那么整个输出里就只有一个SELECT,这样一来每一行在这个列上都会显示一个1。如果语句中使用了子查询、集合操作、临时表等情况,会给ID列带来很大的复杂性。
select_type
语句所使用的查询类型。是简单SELECT还是复杂SELECT(如果是后者,显示它属于哪一种复杂类型)。常用有以下几种标记类型。
- DEPENDENT SUBQUERY
子查询内层的第一个SELECT,依赖于外部查询的结果集。
- DEPENDENT UNION
子查询中的UNION,且为UNION中从第二个SELECT开始的后面所有SELECT,同样依赖于外部查询的结果集。
- PRIMARY
子查询中的最外层查询,注意并不是主键查询。
- SIMPLE
除子查询或UNION之外的其他查询。
- SUBQUERY
子查询内层查询的第一个SELECT,结果不依赖于外部查询结果集。
- UNCACHEABLE SUBQUERY
结果集无法缓存的子查询。
- UNION
UNION语句中的第二个SELECT开始后面的所有SELECT,第一个SELECT为PRIMARY。
- UNION RESULT
UNION中的合并结果。从UNION临时表获取结果的SELECT。
- DERIVED
衍生表查询(FROM子句中的子查询)。MySQL会递归执行这些子查询,把结果放在临时表里。在内部,服务器就把当做一个"衍生表"那样来引用,因为临时表就是源自子查询。
table
这一步所访问的数据库中表的名称或者SQL语句指定的一个别名表。这个值可能是表名、表的别名或者一个为查询产生的临时表的标识符,如派生表、子查询或集合。
type
表的访问方式。以下列出了各种不同类型的表连接,依次是从最好的到最差的。
- system
系统表,表只有一行记录。这是const表连接类型的一个特例。
- const
读常量,最多只有一行匹配的记录