正文
重启数据库后即持久化开启慢查询,查询验证如下:
mysql> show variables like '%_query_%';
+------------------------------+-----------------------------------+
| Variable_name | Value |
+------------------------------+-----------------------------------+
| have_query_cache | YES |
| long_query_time | 1.000000 |
| slow_query_log | ON |
| slow_query_log_file | /var/lib/mysql/localhost-slow.log |
+------------------------------+-----------------------------------+
6 rows in set (0.01 sec)
如上图,是执行时间超过 1 秒的 SQL 语句(测试):
分析 MySQL 慢查询日志,利用 Explain 关键字可以模拟优化器执行 SQL 查询语句,来分析 SQL 慢查询语句。
下面我们的测试表是一张 137w 数据的 app 信息表,我们来举例分析一下。
SQL 示例如下:
-- 1.185s
SELECT * from vio_basic_domain_info where app_name like '%翻译%' ;
这是一条普通的模糊查询语句,查询耗时:1.185s,查到了 148 条数据。
我们用 Explain 分析结果如下表,根据表信息可知:该 SQL 没有用到字段 app_name 上的索引,查询类型是全表扫描,扫描行数 137w。
mysql> EXPLAIN SELECT * from vio_basic_domain_info where app_name like '%翻译%' ;
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| 1 | SIMPLE | vio_basic_domain_info | NULL | ALL | NULL | NULL | NULL | NULL | 1377809 | 11.11 | Using where |
+----+-------------+-----------------------+------------+------+---------------+------+---------+------+---------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
当这条 SQL 使用到索引时,SQL 如下:查询耗时:0.156s,查到 141 条数据:
-- 0.156s
SELECT * from vio_basic_domain_info where app_name like '翻译%' ;
Explain 分析结果如下表;根据表信息可知:该 SQL 用到了 idx_app_name 索引,查询类型是索引范围查询,扫描行数 141 行。
由于查询的列不全在索引中(select *),因此回表了一次,取了其他列的数据。
mysql> EXPLAIN SELECT * from vio_basic_domain_info where app_name like '翻译%' ;
+----+-------------+-----------------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | vio_basic_domain_info | NULL | range | idx_app_name | idx_app_name | 515 | NULL | 141 | 100.00 | Using index condition |
+----+-------------+-----------------------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
当这条 SQL 使用到覆盖索引时,SQL 如下:查询耗时:0.091s,查到 141 条数据。
-- 0.091s
SELECT app_name from vio_basic_domain_info where app_name like '翻译%' ;
Explain 分析结果如下表;根据表信息可知:和上面的 SQL 一样使用到了索引,由于查询列就包含在索引列中,又省去了 0.06s 的回表时间。
mysql> EXPLAIN SELECT app_name from vio_basic_domain_info
where app_name like '翻译%' ;
+----+-------------+-----------------------+------------+-------+---------------+--------------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------------------+------------+-------+---------------+--------------+---------+------+------+
----------+--------------------------+
| 1 | SIMPLE | vio_basic_domain_info | NULL | range | idx_app_name | idx_app_name | 515 | NULL | 141 | 100.00 | Using where; Using index |