搜索
首页数据库mysql教程总结分享之mysql慢查询优化的思路

本篇文章给大家带来了关于mysql的相关知识,其中主要介绍了关于慢查询优化的相关问题,包括了利用慢查询日志定位慢查询SQL、通过explain分析慢查询SQL、修改SQL尽量让SQL走索引,下面一起来看一下,希望对大家有帮助。

总结分享之mysql慢查询优化的思路

推荐学习:mysql视频教程

1 慢查询优化思路

当发生慢查询的时候,优化的思路为:

  • 利用慢查询日志定位慢查询 SQL

  • 通过 explain 分析慢查询 SQL

  • 修改 SQL,尽量让 SQL 走索引

2 慢查询日志

MySQL 提供了一个功能——慢查询日志,会记录查询时间超过指定时间阈值的 SQL 到日志中,便于我们定位慢查询并且优化对应的 SQL 语句。

首先查看 MySQL 中关于慢查询相关的全局变量:

mysql> show global variables like '%quer%';
+----------------------------------------+-------------------------------+
| Variable_name                          | Value                         |
+----------------------------------------+-------------------------------+
| binlog_rows_query_log_events           | OFF                           |
| ft_query_expansion_limit               | 20                            |
| have_query_cache                       | YES                           |
| log_queries_not_using_indexes          | OFF                           |
| log_throttle_queries_not_using_indexes | 0                             |
==========================================================================
| long_query_time                        | 10.000000                     |【1】慢查询的时间阈值
==========================================================================
| query_alloc_block_size                 | 8192                          |
| query_cache_limit                      | 1048576                       |
| query_cache_min_res_unit               | 4096                          |
| query_cache_size                       | 16777216                      |
| query_cache_type                       | OFF                           |
| query_cache_wlock_invalidate           | OFF                           |
| query_prealloc_size                    | 8192                          |
==========================================================================
| slow_query_log                         | OFF                           |【2】慢查询日志是否开启
| slow_query_log_file                    | /var/lib/mysql/Linux-slow.log |【3】慢查询日志文件存储位置
==========================================================================
+----------------------------------------+-------------------------------+
15 rows in set (0.00 sec)

这里主要关注三个变量:

  • long_query_time,慢查询的时间阈值,单位秒,如果一个 SQL 语句的执行时间超过这个值,那么 MySQL 就认定其为慢查询

  • slow_query_log,慢查询日志功能是否开启,默认关闭,开启后记录慢查询

  • slow_query_log_file,慢查询日志文件的存储位置

默认慢查询日志功能是关闭的,因此我们需要启动该功能

# 开启慢查询日志
mysql> set global slow_query_log=ON;
Query OK, 0 rows affected (0.00 sec)
# 设置慢查询时间阈值
mysql> set long_query_time=1;
Query OK, 0 rows affected (0.00 sec)

这样子设置后,MySQL 重启会丢失这些配置,需要在配置文件中修改才会永久有效。

3 explain

我们可以使用 explain 分析 SQL 语句的执行情况,例如:

mysql> explain select sum(1+2);

执行结果如下,可以看到有很多字段

24.png

我们主要看看一些重要的字段:

  • select_type 表示查询语句的查询类型,包括简单查询、子查询等等

  • table 表示查询的表,不一定是存在表,可能是本次查询中得到的临时表

  • type 表示检索类型,使用全表扫描、还是索引扫描等

  • possible_keys表示可能使用的索引列

  • keys表示查询中实际使用的索引列,由查询优化器决定

3.1 select_type 字段

25.png

3.2 type 字段

对于 InnoDB 存储引擎,type列通常都是all或者index。

关于 type 字段的值,其从上到下对应的 SQL 的执行性能逐渐变差。

26.png

3.3 extra 字段

27.png

4 慢查询例子

准备数据,数据表结构:

create table user_info_large (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`account` VARCHAR(20) NOT NULL COMMENT '用户账号',
`name` VARCHAR(20) NOT NULL COMMENT '用户名',
`password` VARCHAR(20) not null COMMENT '用户密码',
`area` VARCHAR(20) NOT NULL COMMENT '用户地址',
`signature` VARCHAR(50) not null COMMENT '个性签名',
PRIMARY KEY (`id`) COMMENT '主键',
UNIQUE (`account`) COMMENT '唯一索引',
KEY `index_area_signture` (`area`,  `signature`)  COMMENT '组合索引'
);

随机生成 200w 条数据

mysql> select count(id) from user_info_large;
+-----------+
| count(id) |
+-----------+
|   2000000 |
+-----------+
1 row in set (0.38 sec)

截取部分数据:

28.png

执行以下 SQL 语句,没有使用任何索引字段:

SELECT name from user_info_large ORDER BY name desc limit 0,100000;

Navicat 工具显示的查询时间如下,这并不是 MySQL 真正执行 SQL 的时间,这里面包含了网络传输等时间:

29.png

SQL 具体的查询时间可以查看慢查询日志:

# Time: 2022-09-26T13:44:18.405459Z
# User@Host: root[root] @  [ip]  Id:  1893
# Query_time: 10.162999  Lock_time: 0.000113 Rows_sent: 100000  Rows_examined: 2100000
SET timestamp=1664199858;
SELECT name from user_info_large ORDER BY name desc limit 0,100000;

关于其中一些信息的说明:

  • Time:SQL 执行的开始时间

  • Query_time:SQL 语句查询花费的时间,可以看到花费了 10 秒钟

  • Lock_time:等待锁表的时间

  • Rows_sent:语句返回的记录数

  • Rows_examined:从存储引擎中返回的记录数

正在执行的慢查询是不会被记录到慢查询日志的,只有等待其执行完毕才会记录到日志中。

我们可以使用 show processlist 查看正在执行 SQL 的线程。

再执行以下语句,使用索引 account 字段:

SELECT account from user_info_large ORDER BY account desc limit 0,100000;

查看慢查询日志,并没有被记录下来。

现在分别使用 explain 查看 SQL 语句的执行情况:

explain SELECT name from user_info_large ORDER BY name desc limit 0,100000;

分析情况如下:

30.png

可以看到没有使用到索引,type 为 ALL 表示全表扫描,效率最差,并且 Extra  也是外部排序。

再看看这条 SQL 语句:

explain SELECT account from user_info_large ORDER BY account desc limit 0,100000;

分析情况如下:

31.png

type 为 index,使用了索引,使用的索引字段为 account,Extra 显示为使用索引排序。

因此,在实际开发中,我们可以针对慢查询的 SQL,使用 explain 分析语句,根据分析情况以及索引的设计,重新设计 SQL 语句,让 SQL 语句尽量走索引,走合适的索引。

5 优化器与索引

在执行 SQL 时,MySQL 的优化器会根据情况选择索引,但并不能保证其执行时间一定最短,我们可以根据实际情况使用 force key (index) 让 SQL 语句强制走某个索引。

例如,以下语句执行后,key 字段为 account,并没有走主键索引。

explain SELECT count(id) from user_info_large;

32.png

如果使用 force key,就可以强制令语句走主键索引。

explain SELECT count(id) from user_info_large force key (PRIMARY);

33.png

6 总结

在项目中如果发现部分 SQL 语句执行缓慢,等待查询时间长,可以考虑优化慢查询,具体思路为:

  • 通过慢查询日志定位 SQL

  • 使用 explain 分析 SQL

  • 修改 SQL,令其走合适的索引

 在使用 explain 时,我们主要关注这些字段:

  • type

  • key

  • Extra

在编写 SQL 使用索引的时候,我们尽量注意一下规则:

  • 模糊查询不要使用通配符 % 开头,例如 like '%abc'

  • 使用 or 关键字时,两边的字段都要有索引。或者使用 union 替代 or

  • 使用复合索引遵循最左原则

  • 索引字段不要参加表达式运算、函数运算

推荐学习:mysql视频教程

以上是总结分享之mysql慢查询优化的思路的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:掘金。如有侵权,请联系admin@php.cn删除
说明InnoDB重做日志和撤消日志的作用。说明InnoDB重做日志和撤消日志的作用。Apr 15, 2025 am 12:16 AM

InnoDB使用redologs和undologs确保数据一致性和可靠性。1.redologs记录数据页修改,确保崩溃恢复和事务持久性。2.undologs记录数据原始值,支持事务回滚和MVCC。

在解释输出(类型,键,行,额外)中要查找的关键指标是什么?在解释输出(类型,键,行,额外)中要查找的关键指标是什么?Apr 15, 2025 am 12:15 AM

EXPLAIN命令的关键指标包括type、key、rows和Extra。1)type反映查询的访问类型,值越高效率越高,如const优于ALL。2)key显示使用的索引,NULL表示无索引。3)rows预估扫描行数,影响查询性能。4)Extra提供额外信息,如Usingfilesort提示需要优化。

在解释中使用临时状态以及如何避免它是什么?在解释中使用临时状态以及如何避免它是什么?Apr 15, 2025 am 12:14 AM

Usingtemporary在MySQL查询中表示需要创建临时表,常见于使用DISTINCT、GROUPBY或非索引列的ORDERBY。可以通过优化索引和重写查询避免其出现,提升查询性能。具体来说,Usingtemporary出现在EXPLAIN输出中时,意味着MySQL需要创建临时表来处理查询。这通常发生在以下情况:1)使用DISTINCT或GROUPBY时进行去重或分组;2)ORDERBY包含非索引列时进行排序;3)使用复杂的子查询或联接操作。优化方法包括:1)为ORDERBY和GROUPB

描述不同的SQL交易隔离级别(读取未读取,读取,可重复的读取,可序列化)及其在MySQL/InnoDB中的含义。描述不同的SQL交易隔离级别(读取未读取,读取,可重复的读取,可序列化)及其在MySQL/InnoDB中的含义。Apr 15, 2025 am 12:11 AM

MySQL/InnoDB支持四种事务隔离级别:ReadUncommitted、ReadCommitted、RepeatableRead和Serializable。1.ReadUncommitted允许读取未提交数据,可能导致脏读。2.ReadCommitted避免脏读,但可能发生不可重复读。3.RepeatableRead是默认级别,避免脏读和不可重复读,但可能发生幻读。4.Serializable避免所有并发问题,但降低并发性。选择合适的隔离级别需平衡数据一致性和性能需求。

MySQL与其他数据库:比较选项MySQL与其他数据库:比较选项Apr 15, 2025 am 12:08 AM

MySQL适合Web应用和内容管理系统,因其开源、高性能和易用性而受欢迎。1)与PostgreSQL相比,MySQL在简单查询和高并发读操作上表现更好。2)相较Oracle,MySQL因开源和低成本更受中小企业青睐。3)对比MicrosoftSQLServer,MySQL更适合跨平台应用。4)与MongoDB不同,MySQL更适用于结构化数据和事务处理。

MySQL索引基数如何影响查询性能?MySQL索引基数如何影响查询性能?Apr 14, 2025 am 12:18 AM

MySQL索引基数对查询性能有显着影响:1.高基数索引能更有效地缩小数据范围,提高查询效率;2.低基数索引可能导致全表扫描,降低查询性能;3.在联合索引中,应将高基数列放在前面以优化查询。

MySQL:新用户的资源和教程MySQL:新用户的资源和教程Apr 14, 2025 am 12:16 AM

MySQL学习路径包括基础知识、核心概念、使用示例和优化技巧。1)了解表、行、列、SQL查询等基础概念。2)学习MySQL的定义、工作原理和优势。3)掌握基本CRUD操作和高级用法,如索引和存储过程。4)熟悉常见错误调试和性能优化建议,如合理使用索引和优化查询。通过这些步骤,你将全面掌握MySQL的使用和优化。

现实世界Mysql:示例和用例现实世界Mysql:示例和用例Apr 14, 2025 am 12:15 AM

MySQL在现实世界的应用包括基础数据库设计和复杂查询优化。1)基本用法:用于存储和管理用户数据,如插入、查询、更新和删除用户信息。2)高级用法:处理复杂业务逻辑,如电子商务平台的订单和库存管理。3)性能优化:通过合理使用索引、分区表和查询缓存来提升性能。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
1 个月前By尊渡假赌尊渡假赌尊渡假赌

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具