1. 优化简介
MySQL性能优化包括:查询优化、数据库结构优化、MySQL服务器优化等。
2. 查询优化
2.1 分析查询语句
MySQL提供EXPLAIN和DESCRIBE,用来分析查询语句。
EXPLAIN语句的基本语法:
EXPLAIN [EXTENDED] SELECT select_options
其中,EXTENDED用于EXPLAIN产生附加信息,select_options是SELECT语句的查询选项,包括FROM WHERE子句等。
mysql> EXPLAIN SELECT * FROM product;
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
| 1 | SIMPLE | product | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | NULL |
+----+-------------+---------+------------+------+---------------+------+---------+------+------+----------+-------+
其中,
id:SELECT识别符,SELECT的查询序列号。
select_type:SELECT语句的类型。
取值包括:
(1)SIMPLE:简单查询,不包括连接查询和子查询
(2)PRIMARY:主查询,或最外层的查询语句
(3)UNION:连接查询的第2个或后面的查询语句
(4)DEPENDENT UNION:连接查询中的第2个或后面的SELECT语句,取决于外面的查询
(5)UNION RESULT:连接查询的结果
(6)SUBQUERY:子查询中的第1个SELECT语句
(7)DEPENDENT SUBQUERY:子查询中的第1个SELECT,取决于外面的查询
(8)DERIVED:导出表的SELECT(FROM子句的子查询)
table:查询的表
type:表的连接类型
表的连接类型从最佳到最差顺序:
(1)system:该表是仅有一行的系统表,是const连接类型的一个特例。
(2)const:数据表最多只有一个匹配行,const表查询速度很快,因为只读取一次。
const用于使用常量值比较PRIMARY KEY或UNIQUE索引场合。
mysql> EXPLAIN SELECT * FROM product WHERE id = 1;
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
| 1 | SIMPLE | product | NULL | const | PRIMARY | PRIMARY | 4 | const | 1 | 100 | NULL |
+----+-------------+---------+------------+-------+---------------+---------+---------+-------+------+----------+-------+
(3)eq_ref:用在一个索引的所有部分被连接使用并且索引是UNIQUE或PRIMARY KEY。
eq_ref可以用于使用"="操作符比较带索引的列。比较值为常量或一个在该表前面所读取的列的表达式。
mysql> EXPLAIN SELECT
-> product.*
-> FROM
-> product
-> INNER JOIN category ON product.category_id = category.id;
+----+-------------+-----------+------------+--------+---------------+---------+---------+------------------------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+--------+---------------+---------+---------+------------------------+------+----------+-------------+
| 1 | SIMPLE | product | NULL | ALL | NULL | NULL | NULL | NULL | 118 | 100 | Using where |
| 1 | SIMPLE | category | NULL | eq_ref | PRIMARY | PRIMARY | 4 | db.product.category_id | 1 | 100 | Using index |
+----+-------------+-----------+------------+--------+---------------+---------+---------+------------------------+------+----------+-------------+