MySQL慢查询优化

慢查询

什么是慢查询

慢查询,就是耗时较长、速度较慢的查询。

mysql提供了API来支持用户查看哪些查询比较慢。

mysql慢查询相关参数说明

slow_query_log 慢查询开启状态
slow_query_log_file 慢查询日志存放的位置(这个目录需要MySQL的运行帐号的可写权限,一般设置为MySQL的数据存放目录)
long_query_time 查询超过多少秒才记录

查看慢查询相关参数

通过mysql自带的客户端设置:cmd进入bin目录下,运行 mysql -uroot -p命令登入后:

mysql> show variables like 'slow_query%';
+---------------------------+----------------------------------+
| Variable_name             | Value                            |
+---------------------------+----------------------------------+
| slow_query_log            | OFF                              |
| slow_query_log_file       | /mysql/data/localhost-slow.log   |
+---------------------------+----------------------------------+

mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+

设置相关参数、开启慢查询日志记录

方法一:全局变量设置

通过mysql自带的客户端设置:cmd进入bin目录下,运行 mysql -uroot -p命令登入后:

--将 slow_query_log 全局变量设置为“ON”状态
mysql> set global slow_query_log='ON'; 

--设置慢查询日志存放的位置
mysql> set global slow_query_log_file='/usr/local/mysql/data/slow.log';

--查询超过1秒就记录
mysql> set global long_query_time=1;
方法二:配置文件设置

Linux下编辑etc/文件夹下的my.cnf,Windows下编辑my.ini

5.5以上版本,在[mysqld]下的下方加入

[mysqld]
slow_query_log = ON
slow_query_log_file = /usr/local/mysql/data/slow.log
long_query_time = 1

5.0、5.1等版本配置如下选项

log-slow-queries="mysql_slow_query.log"  

重启MySQL服务

service mysqld restart

查看设置后的参数

mysql> show variables like 'slow_query%';
+---------------------+--------------------------------+
| Variable_name       | Value                          |
+---------------------+--------------------------------+
| slow_query_log      | ON                             |
| slow_query_log_file | /usr/local/mysql/data/slow.log |
+---------------------+--------------------------------+

mysql> show variables like 'long_query_time';
+-----------------+----------+
| Variable_name   | Value    |
+-----------------+----------+
| long_query_time | 1.000000 |
+-----------------+----------+

测试

1.执行一条慢查询SQL语句

mysql> select sleep(2);
2.查看是否生成慢查询日志

ls /usr/local/mysql/data/slow.log
如果日志存在,MySQL开启慢查询设置成功!

查看慢查询语句

可以使用MySQL自带的mysqldumpslow命令,其用法如下

排序参数-s,取值有 c(按照记录次数排序)、t(按照查询的发生时间排序)、l(按照耗时排序)、r(按照结果集数目排序),ac、at、al、ar表示相应的倒序。

取前多少个-t,即 top n

正则匹配-g

分析慢查询原因:

Explain或者DESC命令

DESC命令的使用很简单,例:sql>desc select * from easy_sys_user;

Explain 待续……

优化慢查询:

1、新建索引

为了减少磁盘IO消耗,MySQL的索引存储采用B+树结构,在B+树中,如果数据项是复合结构,则最左边的是第一比较因子,如果没有给出第一比较因子的值,则会返回所有数据,即索引没有起到作用。另如果遇到的比较因子是一个范围时,它后面的所有比较因子将都用不上。

根据B+树的这种特性,要求优化慢查询建立联合索引的时候坚持最左匹配原则,即查询条件是等值查询的字段作为联合索引的第一个字段。

Explain 待续……

Explain

什么是explain

explain是mysql提供给开发人员的工具,它向开发人员解释了mysql如何执行的SQL语句,通过这些解释,开发人员或许可以明白查询的效率慢的原因,可以对 SQL 语句做相应的优化,提高执行效率。

如何使用explain

调用 Explain,只需要在 SQL 语句前添加 explain 关键字即可。

一般情况下,添加 explain 关键字后,认为 MySQL 不会执行查询,但是如果在 from 子句中包含子查询,那么 MySQL 实际上会执行子查询,将其子查询的结果放在一个临时表中,然后完成外层查询优化。

Explain提供了哪些信息

调用 Explain 后,MySQL 会返回一行或者多行记录,通过这些记录就可以知道 SQL 语句的执行情况了。

每行记录都包含了以下几个字段

  • id:执行编号,标识 select 所属的行。一个sql语句在数据库上可能需要执行多个查询,比如in。explain给每个查询都编号,编号越大,查询越先执行
  • select_type:select 查询的类型
  • table:查询的是哪个表
  • partitions:匹配的分区
  • type:关联类型,或者访问类型
  • possible_keys:该查询可以选用的索引
  • key:该查询选用的索引
  • key_len:索引中使用的字节数
  • ref:显示上述表的连接匹配条件,即哪些列或常量被用于查询索引列上的值
  • rows:估计为了找到所需行而要读取的行数
  • filtered:按表条件过滤的行的百分比
  • Extra:额外的信息

Explain字段详解

  • id
    该列总是包含一个编号,标识 select 所属的行。如果语句当中没有子查询或联合查询,那么只会有唯一的 select,于是每一行在这个列中都将显示一个 1。否则,内层的 select 语句一般会顺序编号,对应于原始语句中的位置。

id 值越大,越先执行。

  • select_type
    该列指明了查询的类型,以下为常见的取值

SIMPLLE:简单查询,该查询不包含 UNION 或子查询
PRIMARY:如果查询包含 UNION 或子查询,则最外层的查询被标识为 PRIMARY
UNION:表示此查询是 UNION 中的第二个或者随后的查询
DEPENDENT:UNION 满足 UNION 中的第二个或者随后的查询,其次取决于外面的查询
UNION RESULT:UNION 的结果
SUBQUERY:子查询中的第一个 select 语句
DEPENDENT SUBQUERY:子查询中的 第一个 select,同时取决于外面的查询
DERIVED:派生表 select,包含在 from 字句的子查询中的查询
UNCACHEABLE SUBQUERY:满足是子查询中的第一个 select 语句,同时意味着 select 中的某些特性阻止结果被缓存于一个 Item_cache 中
UNCACHEABLE UNION:满足此查询是 UNION 中的第二个或者随后的查询,同时意味着 select 中的某些特性阻止结果被缓存于一个 Item_cache 中

  • table
    该列显示了对应行正在访问哪个表,或者该表的别名。

  • partitions
    记录将与查询匹配的分区,非分区表的值为NULL。

  • type
    该列称为关联类型或者访问类型,它指明了 MySQL 决定如何查找表中符合条件的行,同时为判断查询是否高效提供了重要的依据。

以下为常见的取值

ALL:全表扫描,这个类型是性能最差的查询之一。通常来说,我们的查询不应该出现 ALL 类型,因为这样的查询,在数据量最大的情况下,对数据库的性能是巨大的灾难。
index:全索引扫描,和 ALL 类型类似,只不过 ALL 类型是全表扫描,而 index 类型是扫描全部的索引,主要优点是避免了排序,但是开销仍然非常大。如果在 Extra 列看到 Using index,说明正在使用覆盖索引,只扫描索引的数据,它比按索引次序全表扫描的开销要少很多。
range:范围扫描,就是一个有限制的索引扫描,它开始于索引里的某一点,返回匹配这个值域的行。这个类型通常出现在 =、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN、IN() 的操作中,key 列显示使用了哪个索引,当 type 为该值时,则输出的 ref 列为 NULL,并且 key_len 列是此次查询中使用到的索引最长的那个。
ref:一种索引访问,也称索引查找,它返回所有匹配某个单个值的行。此类型通常出现在多表的 join 查询, 针对于非唯一或非主键索引, 或者是使用了最左前缀规则索引的查询。
eq_ref:使用这种索引查找,最多只返回一条符合条件的记录。在使用唯一性索引或主键查找时会出现该值,非常高效。
const、system:该表至多有一个匹配行,在查询开始时读取,或者该表是系统表,只有一行匹配。其中 const 用于在和 primary key 或 unique 索引中有固定值比较的情形。
NULL:在执行阶段不需要访问表。
该列取不同值的执行效率依次是

ALL < index < range < ref < eq_ref < const < system < NULL

一般来说,至少要保证查询达到 range 级别,最好能达到 ref 级别。

  • possible_keys
    该列显示了查询可以选用哪些索引,但是列出来的索引,可能对于后续优化过程是没有用的。

  • key
    该列显示了查询选用了哪个索引,如果该索引没有出现在 possible_keys 列中,那么选用它可能出于另外的原因,比如,它可能选择了一个覆盖索引。

  • key_len
    该列显示了在索引里使用的字节数,当 key 列的值为 NULL 时,则该列也是 NULL。如果正在使用的只是索引里的某些列,那么可以通过用该列的值算出来具体是哪些列。

  • ref
    该列显示了哪些字段或者常量被用来和 key 配合从表中查询记录出来。

  • rows
    该列显示了估计要找到所需的行而要读取的行数,这个值是个估计值,原则上值越小越好。

filtered
该列表示根据条件过滤的表行的估计百分比,和 rows 相乘,表示和查询计划里前一个表关联的行数。

Extra
该列显示了有关 MySQL 如何解析查询的其它信息。

以下为常见的取值

Using index:使用覆盖索引,表示查询索引就可查到所需数据,不用扫描表数据文件,往往说明性能不错。
Using Where:在存储引擎检索行后再进行过滤,使用了 where 从句来限制哪些行将与下一张表匹配或者是返回给用户。
Using temporary:在查询结果排序时会使用一个临时表,一般出现于排序、分组和多表 join 的情况,查询效率不高,建议优化。
Using filesort:对结果使用一个外部索引排序,而不是按索引次序从表里读取行,一般有出现该值,都建议优化去掉,因为这样的查询 CPU 资源消耗大。

对于MySQL慢查询优化,有几个常见的方法和技巧可以尝试: 1. 确定慢查询:首先使用MySQL慢查询日志或性能分析工具(如Percona Toolkit)来确定哪些查询较慢。这样可以帮助你了解具体的问题。 2. 优化查询语句:检查慢查询中的SQL语句并进行优化。你可以考虑添加适当的索引以提高查询性能,或者重写复杂的查询语句以简化其逻辑。 3. 优化数据库结构:检查数据库表的设计和结构,确保表中的字段类型、索引和约束等设置是合理的。合理的数据库设计可以提高查询性能。 4. 避免全表扫描:尽量避免在大表上执行全表扫描操作,可以通过添加索引或者改进查询条件来避免全表扫描。 5. 调整系统配置参数:根据数据库负载和硬件性能,调整MySQL的配置参数,如缓冲区大小、连接池大小等,以提高系统性能。 6. 使用缓存:考虑使用缓存技术(如Redis)来缓存常用的查询结果,减轻数据库的压力。 7. 分离读写操作:将读操作和写操作分离到不同的数据库实例或服务器上,可以提高数据库的并发性能。 8. 使用慢查询日志或监控工具:定期分析慢查询日志,或者使用监控工具(如Prometheus和Grafana)来实时监测数据库性能,并及时调整和优化。 这些是一些常见的MySQL慢查询优化方法,具体的优化策略需要根据具体情况进行调整和实施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值