在 MySQL 优化的环节上,咱们首先须要晓得的就是咱们以后的这句 SQL 语句在理论的数据库中到底是怎么执行的,能力谈要如何优化它。而在 MySQL 中,就给咱们提供了模仿语句执行的一个十分好用的关键字:EXPLAIN。EXPLAIN 能够用来查看 SQL 语句的执行成果,能够帮忙抉择更好的索引和优化查问语句,写出更好的优化语句。因而明天咱们就来讲一讲这个关键字的一些根底的用法与利用。
一、应用办法
EXPLAIN 的应用办法非常简单:
mysql> EXPLAIN SELECT * FROM user;
简略来说,就是在原有的 SQL 语句后面加上 EXPLAIN 关键字,或者说是在 EXPLAIN 关键字后跟这你要查看的 SQL 语句。
二、输入后果
EXPLAIN 语句的输入后果才是咱们想要的数据,也是咱们剖析的重点。
咱们先来看看下面的语句所给到的对应的后果的模式:
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | user | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
EXPLAIN 语句给到咱们的数据总共有 10 列,接下来咱们看一下一些在性能优化上有比拟重要作用的数据列所代表的意思。
1.id
这个是 select 查问的序列号。
2.select_type
当咱们的 SQL 语句是非 select 语句的时候(即 delete,update…),这个字段的值就是对应的操作类型(delete,update…)。
mysql> EXPLAIN INSERT INTO user VAULES(2,'ahong','31');
此时的输入 select_type 就是咱们对应的 INSERT:
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | INSERT | user | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
而当 SQL 语句时 select 语句的时候,他就是对应的一些具体的 select 的类型,能够有如下几种:
SIMPLE:简略 SELECT(不应用 UNION 或子查问等)
PRIMARY:最里面的 SELECT
UNION:UNION 中的第二个或前面的 SELECT 语句
DEPENDENT UNION:UNION 中的第二个或前面的 SELECT 语句,取决于里面的查问
UNION RESULT:UNION 的后果。SUBQUERY:子查问中的第一个 SELECT
DEPENDENT SUBQUERY:子查问中的第一个 SELECT,取决于里面的查问
DERIVED:导出表的 SELECT(FROM 子句的子查问)
上面就是一个最简略的 SIMPLE 查问的例子:
mysql> EXPLAIN SELECT * FROM user;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | user | NULL | ALL | NULL | NULL | NULL | NULL | 3 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------+
3.table
显示这一步操作所拜访的数据是对于哪一张表的。
4.partitions
显示表所应用的分区,如果要统计十年公司订单的金额,能够把数据分为十个区,每一年代表一个区。这样能够大大的进步查问效率。
5.type
这是最重要的一列。显示了连贯应用了哪品种别,有无应用索引。是剖析查问性能的要害。
后果性能从优到差别离有以下的状况:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
而这几种状况所代表的意义如下:
system、const:能够将查问的变量转为常量. 如 id=1; id 为 主键或惟一键.
eq_ref:拜访索引, 返回某繁多行的数据.(通常在联接时呈现,查问应用的索引为主键或惟一键)
ref:拜访索引, 返回某个值的数据.(能够返回多行) 通常应用 = 时产生
range:这个连贯类型应用索引返回一个范畴中的行,比方应用 > 或 < 查找货色,并且该字段上建有索引时产生的状况(注: 不肯定好于 index)
index:以索引的程序进行全表扫描,长处是不必排序, 毛病是还要全表扫描
ALL:全表扫描,应该尽量避免_
一般来说,得保障查问至多达到 range 级别,最好能达到 ref,否则就可能会呈现性能问题。
type 类型具体的例子能够参考 https://blog.csdn.net/dennis2…
6.possible_key
显示查问语句有可能会应用到的索引列。取值可能为一个,多个或者 null。
7.key
key 列显示的是该查问语句理论应用的索引列。如为 null,则示意没有应用索引。
展现一下 possible_key 和 key 的实际效果:
上面是一个在 age 列上建设索引的数据表,咱们进行以下的查问
mysql> explain select * from user where age = 1;
会失去以下的后果:
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
| 1 | SIMPLE | user | NULL | ref | age | age | 5 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
后果给咱们指出了以后查问所应用的索引列是 age,实际上也正是这样。
8.key_len
显示的是以后的查问语句所应用的索引的长度。在不损失精确性的状况下,长度越短越好.
9.ref
援用到的上一个表的列。
10.rows
依据表的状况和查问语句的状况,MySQL 会估算出返回最终后果所必须查看的行的数量。该列的值越大查问效率越差。
11.filtered
一个百分比的值,和 rows 列的值一起应用,能够预计出查问执行打算 (QEP) 中的前一个表的后果集,从而确定 join 操作的循环次数。小表驱动大表,加重连贯的次数。
12.extra
对于 MySQL 如何解析查问的额定信息,次要有以下几种:
Extra 中蕴含的值:using index:只用到索引, 能够防止拜访表,性能很高。using where:应用到 where 来过滤数据,不是所有的 where clause 都要显示 using where. 如以 = 形式拜访索引。using tmporary:用到长期表去解决以后的查问。using filesort:用到额定的排序,此时 mysql 会依据联接类型浏览所有符合条件的记录,并保留排序关键字和行指针,而后排序关键字并按程序检索行。(当应用 order by v1, 而没用到索引时, 就会应用额定的排序)。range checked for eache record(index map:N):没有好的索引能够应用。Using index for group-by:__表明能够在索引中找到分组所需的所有数据,不须要查问理论的表。explain select user_id from t_order group by user_id;_
extra 列往往能够蕴含很多信息,详情能够看:https://blog.csdn.net/poxiaon…