Mysql系列-性能优化神器EXPLAIN使用介绍及分析
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Mysql系列-性能优化神器EXPLAIN使用介绍及分析,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含12275字,纯文字阅读大概需要18分钟。
内容图文
![Mysql系列-性能优化神器EXPLAIN使用介绍及分析](/upload/InfoBanner/zyjiaocheng/508/9cffd72a8cc04bcbbe514a0b0adecbe4.jpg)
下面是我结合我自己创建的表以及执行相关sql语句总结的相关知识点。
准备
为了接下来方便演示 EXPLAIN 的使用, 首先我们需要建立两个测试用的表, 并添加相应的数据:
DROP TABLE IF EXISTS `customers`; CREATE TABLE `customers` ( `customerNumber` int(11) NOT NULL, `customerName` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `contactLastName` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `contactFirstName` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `phone` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `addressLine1` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `addressLine2` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `city` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `state` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `postalCode` varchar(15) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL, `country` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, `salesRepEmployeeNumber` int(11) NULL DEFAULT NULL, `creditLimit` decimal(10, 2) NULL DEFAULT NULL, PRIMARY KEY (`customerNumber`) USING BTREE, INDEX `salesRepEmployeeNumber`(`salesRepEmployeeNumber`) USING BTREE, INDEX `customers_idx_combine_1`(`customerName`, `phone`, `customerNumber`) USING BTREE, CONSTRAINT `customers_ibfk_1` FOREIGN KEY (`salesRepEmployeeNumber`) REFERENCES `employees` (`employeeNumber`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
创建表成功后,插入一些测试数据。
EXPLAIN 输出格式
EXPLAIN 命令的输出内容大致如下:
mysql> EXPLAIN SELECT * FROM customers WHERE customerName=‘Herkku Gifts‘ AND phone=‘+47 2267 3215‘ AND customerNumber=167; +----+-------------+-----------+------------+-------+---------------------------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------------------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | customers | NULL | const | PRIMARY,customers_idx_combine_1 | PRIMARY | 4 | const | 1 | 100.00 | NULL | +----+-------------+-----------+------------+-------+---------------------------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
各列的含义如下:
- id: SELECT 查询的标识符. 每个 SELECT 都会自动分配一个唯一的标识符
- select_type: SELECT 查询的类型
- table: 查询的是哪个表
- partitions: 匹配的分区
- type: join 类型
- possible_keys: 此次查询中可能选用的索引
- key: 此次查询中确切使用到的索引
- ken_len: 表示查询优化器使用了索引的字节数
- ref: 哪个字段或常数与 key 一起被使用
- rows: 显示此查询一共扫描了多少行. 这个是一个估计值.
- filtered: 表示此查询条件所过滤的数据的百分比
- extra: 额外的信息
接下来我们详细看一下每个字段的具体含义:
select_type
select_type
表示了查询的类型, 它的常用取值有:
-
SIMPLE:表示此查询不包含 UNION 查询或子查询
-
PRIMARY:表示此查询是最外层的查询
-
UNION:表示此查询是 UNION 的第二或随后的查询
-
DEPENDENT UNION:UNION 中的第二个或后面的查询语句, 取决于外面的查询
-
UNION RESULT:UNION 的结果
-
SUBQUERY:子查询中的第一个 SELECT
-
DEPENDENT SUBQUERY:子查询中的第一个 SELECT, 取决于外面的查询. 即子查询依赖于外层查询的结果
- DERIVED:当子查询是from子句时,其select_type为DERIVED
最常见的查询类别应该是 SIMPLE
了, 比如当我们的查询没有子查询, 也没有 UNION 查询时, 那么通常就是 SIMPLE
类型, 例如:
1.SIMPLE
情况:
mysql> EXPLAIN SELECT * FROM customers WHERE customerName=‘Herkku Gifts‘ AND phone=‘+47 2267 3215‘ AND customerNumber=167; +----+-------------+-----------+------------+-------+---------------------------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------------------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | customers | NULL | const | PRIMARY,customers_idx_combine_1 | PRIMARY | 4 | const | 1 | 100.00 | NULL | +----+-------------+-----------+------------+-------+---------------------------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
2.UNION情况
当通过union来连接多个查询结果时,第二个之后的select其select_type为UNION
mysql> EXPLAIN SELECT customerNumber FROM customers WHERE customerNumber IN (125,144) UNION SELECT customerNumber FROM customers WHERE country IN (‘USA‘,‘France‘); +----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+ | 1 | PRIMARY | customers | NULL | range | PRIMARY | PRIMARY | 4 | NULL | 2 | 100.00 | Using where; Using index | | 2 | UNION | customers | NULL | ALL | NULL | NULL | NULL | NULL | 122 | 20.00 | Using where | | NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | +----+--------------+------------+------------+-------+---------------+---------+---------+------+------+----------+--------------------------+ 3 rows in set, 1 warning (0.00 sec)
3.DEPENDENT UNION与DEPENDENT SUBQUERY
当union作为子查询时,其中第二个union的select_type就是DEPENDENT UNION。第一个子查询的select_type则是DEPENDENT SUBQUERY
mysql> EXPLAIN SELECT * FROM customers WHERE customerNumber IN (SELECT customerNumber FROM customers WHERE customerNumber IN (125,144) UNION SELECT customerNumber FROM customers WHERE country IN (‘USA‘,‘France‘)); +----+--------------------+------------+------------+--------+---------------+---------+---------+------+------+----------+--------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+--------------------+------------+------------+--------+---------------+---------+---------+------+------+----------+--------------------------+ | 1 | PRIMARY | customers | NULL | ALL | NULL | NULL | NULL | NULL | 122 | 100.00 | Using where | | 2 | DEPENDENT SUBQUERY | customers | NULL | eq_ref | PRIMARY | PRIMARY | 4 | func | 1 | 100.00 | Using where; Using index | | 3 | DEPENDENT UNION | customers | NULL | eq_ref | PRIMARY | PRIMARY | 4 | func | 1 | 20.00 | Using where | | NULL | UNION RESULT | <union2,3> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | Using temporary | +----+--------------------+------------+------------+--------+---------------+---------+---------+------+------+----------+--------------------------+ 4 rows in set, 1 warning (0.00 sec)
4.SUBQUERY
子查询中的第一个select其select_type为SUBQUERY
mysql> EXPLAIN SELECT * FROM customers WHERE customerNumber=(SELECT customerNumber FROM customers WHERE customerNumber=124); +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | 1 | PRIMARY | customers | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | | 2 | SUBQUERY | customers | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using index | +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ 2 rows in set, 1 warning (0.00 sec) mysql> EXPLAIN SELECT * FROM customers WHERE customerNumber in (SELECT customerNumber FROM customers WHERE customerNumber=124); +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ | 1 | SIMPLE | customers | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | NULL | | 1 | SIMPLE | customers | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using index | +----+-------------+-----------+------------+-------+---------------+---------+---------+-------+------+----------+-------------+ 2 rows in set, 1 warning (0.00 sec)
思考下为什么一个用了in一个用了=反而select_type就不一样了????
5.DERIVED
mysql> EXPLAIN SELECT * FROM (SELECT COUNT(*) FROM customers WHERE customerNumber=124) a; +----+-------------+------------+------------+--------+---------------+---------+---------+-------+------+----------+-------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+------------+------------+--------+---------------+---------+---------+-------+------+----------+-------------+ | 1 | PRIMARY | <derived2> | NULL | system | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL | | 2 | DERIVED | customers | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using index | +----+-------------+------------+------------+--------+---------------+---------+---------+-------+------+----------+-------------+ 2 rows in set, 1 warning (0.00 sec)
table
表示查询涉及的表或衍生表
partitions
匹配的分区
type
type
字段比较重要, 显示连接使用了何种类型。从最好到最差的连接类型依次分别为const、eq_reg、ref、range、index和ALL 它提供了判断查询是否高效的重要依据依据。
通过 type
字段, 我们判断此次查询是 全表扫描
还是 索引扫描
等。
type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,得保证查询至少达到range级别,最好能达到ref。
type 常用的取值有:
system
: 表中只有一条数据. 这个类型是特殊的 const
类型
const
: 针对主键或唯一索引的等值查询扫描, 最多只返回一行数据. const 查询速度非常快, 因为它仅仅读取一次即可。
例如下面的这个查询, 它使用了主键索引, 因此 type
就是 const
类型的
mysql> EXPLAIN SELECT * FROM customers WHERE customerName=‘Herkku Gifts‘ AND phone=‘+47 2267 3215‘ AND customerNumber=167; +----+-------------+-----------+------------+-------+---------------------------------+---------+---------+-------+------+----------+-------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-----------+------------+-------+---------------------------------+---------+---------+-------+------+----------+-------+ | 1 | SIMPLE | customers | NULL | const | PRIMARY,customers_idx_combine_1 | PRIMARY | 4 | const | 1 | 100.00 | NULL | +----+-------------+-----------+------------+-------+---------------------------------+---------+---------+-------+------+----------+-------+ 1 row in set, 1 warning (0.00 sec)
Mysql系列-性能优化神器EXPLAIN使用介绍及分析
标签:使用介绍 成功 命令 xpl ddr reference cte state 接下来
本文系统来源:https://www.cnblogs.com/MrFiona/p/10925919.html
内容总结
以上是互联网集市为您收集整理的Mysql系列-性能优化神器EXPLAIN使用介绍及分析全部内容,希望文章能够帮你解决Mysql系列-性能优化神器EXPLAIN使用介绍及分析所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。