【 Java 面试八股文】系列会陆续更新 Java 面试中的高频问题,旨在从问题出发,理解 Java 基础,数据结构与算法,数据库,常用框架等。该系列前几期文章可以通过点击文末给出的链接进行查看~
按照惯例——首先要做几点说明:
- 【 Java 面试八股文】中的面试题来源于社区论坛,书籍等资源;感谢使我读到这些宝贵面经的作者们。
- 对于【 Java 面试八股文】中的每个问题,我都会尽可能地写出我自己认为的“完美解答”。但是毕竟我的身份不是一个“真理持有者”,只是一个秉承着开源分享精神的 “knowledge transmitter” & 菜鸡,所以,如果这些答案出现了错误,可以留言写出你认为更好的解答,并指正我。非常感谢您的分享。
- 知识在于“融释贯通”,而非“死记硬背”;现在市面上固然有很多类似于“Java 面试必考 300 题” 这类的文章,但是普遍上都是糟粕,仅讲述其果,而不追其源;希望我的【 Java 面试八股文】可以让你知其然,且知其所以然~
那么,废话不多说,我们正式开始吧!
1、如何定位并优化慢查询 sql?
答
我们从定位到慢查询 sql,再通过分析并进行优化的顺序如下:
- 通过开启慢日志定位到慢查询的 sql
- 使用 explain 工具分析 sql
- 修改并优化 sql
接下来我们就依次通过以上三个步骤来看一下,一条慢查询 sql 是如何被找到,并优化的。
1. 通过开启慢日志定位到慢查询 sql
首先,我们进入到客户端,输入命令:
show variables like '%query%';
命令返回结果如下:
mysql> show variables like '%query%';
+------------------------------+--------------------------------------+
| Variable_name | Value |
+------------------------------+--------------------------------------+
| binlog_rows_query_log_events | OFF |
| ft_query_expansion_limit | 20 |
| have_query_cache | YES |
| long_query_time | 10.000000 |
| query_alloc_block_size | 8192 |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 1048576 |
| query_cache_type | OFF |
| query_cache_wlock_invalidate | OFF |
| query_prealloc_size | 8192 |
| slow_query_log | OFF |
| slow_query_log_file | /var/lib/mysql/23f9bc5132dc-slow.log |
+------------------------------+--------------------------------------+
13 rows in set (0.01 sec)
在这里面,我们需要关注三个变量,分别是:slow_query_log
,slow_query_log_file
以及 long-query_time
。
slow_query_log
目前对应的 Value 值为 OFF,代表慢日志并未开启;slow_query_log_file
是记录慢 sql 的文件,当一条查询 sql 的时间超过 long_query_time
时,就会被记录到慢日志文件中,我们看到 long_query_time
的默认值为 10 s。
首先,我们需要开启慢日志,使用命令:
set global slow_query_log = on;
并且,通常我们会修改 long_query_time
的值。因为如果一条查询 sql 的执行时间超过 10 s 才被定义为慢查询的话,一般是不能被接受的。我们可以按照自己的业务需求,设定相应的值,譬如将其设置为 1 s:
set global long_query_time = 1;
重新连接数据库后,就可以看到刚刚设置的值已经生效了:
mysql> show variables like '%query%';
+------------------------------+--------------------------------------+
| Variable_name | Value |
+------------------------------+--------------------------------------+
| binlog_rows_query_log_events | OFF |
| ft_query_expansion_limit | 20 |
| have_query_cache | YES |
| long_query_time | 1.000000 |
| query_alloc_block_size | 8192 |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 1048576 |
| query_cache_type | OFF |
| query_cache_wlock_invalidate | OFF |
| query_prealloc_size | 8192 |
| slow_query_log | ON |
| slow_query_log_file | /var/lib/mysql/23f9bc5132dc-slow.log |
+------------------------------+--------------------------------------+
13 rows in set (0.01 sec)
除了使用命令进行修改,我们也可以通过修改配置文件(my.cnf)对这些变量进行设置,修改配置文件这种方式会使得这些改动永久保存,不会因为重启数据库服务而失效。
这样,我们就可以通过开启慢日志定位到所有超