MySQL 调优:查询慢除了索引还能因为什么?

文章目录

MySQL 查询慢除了索引还能因为什么?MySQL 查询慢,我们一般也会想到是因为索引,但除了索引还有哪些原因会导致数据库查询变慢呢?

以下以 MySQL 中一条 SQL 的执行流程为基础,分析 MySQL 查询慢除了索引还有哪些原因。

当 MySQL 中一条查询 SQL 在实际进入影响 SQL 执行效率的流程前(主要是优化器流程与执行器流程),首先会进入分析器流程。以 Python 进程为例,以下举例一条 MySQL 语句执行下来会经历哪些流程。

例如在 MySQL 中有一张名为 use_info 的数据表,一个 Python 进程尝试携带账号密码等信息尝试向 MySQL 建立一条网络连接,而 MySQL 的连接管理模块会对这条连接进行管理。

在连接被建立后,Python 应用尝试向 MySQL 服务器执行如下 SQL 查询语句:

sql 复制代码
SELECT user_name,user_address FROM user_info where user_id = 1;

此时 Python 进程需要将 SQL 语句通过网络连接给 MySQL,MySQL 收到 SQL 语句后将在分析器中先判断一下 SQL 语句有没有语法错误。例如 SELECT 是否少写个 L:

sql 复制代码
SEECT user_name,user_address FROM user_info where user_id = 1;

如果 SQL 错误,SELECT 中确实少写个 L,将抛出相关的异常提示:

html 复制代码
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SEECT user_name,user_address FROM user_info where user_id = 1' at line 1

SQL 在分析器过程中执行无误后将到达优化器,而优化器会根据一些规则选择需要使用的索引,之后执行器会调用存储引擎的接口函数,MySQL 中的存储引擎是MySQL 中真正负责读写数据的组件。在如今的 MySQL 数据库开发中,最常用的存储引擎就是 InnoDB 存储引擎。

由于读写磁盘较慢,所以 InnoDB 存储引擎内部增加了一层名为 Buffer Pool 的内存提速设计, 在 Buffer Pool 中即存放行数据又存放索引数据。查询 SQL 到了 InnoDB 中会根据前面优化器里计算得到的索引去查询相应的索引页,如果索引页不在 Buffer Pool 里,则从磁盘里加载到索引页,再通过索引页查询得到数据页的位置。如果这些数据页不在 Buffer Pool 中,则从磁盘里加载进来,最后将得到的一行行数据结果返回给客户端。

在优化器流程与执行器流程过程中,数据库慢查询一般是优化器选错索引导致。这类问题可以通过 EXPLAIN 命令排查。

但是,除了索引之外,还有哪些因素会限制查询速度呢?

情况一:连接数过小

MySQL 的连接管理模块作用是管理客户端和 MySQL 之间的长连接,假设两者之间只有一条连接,那么在执行 SQL 查询之后只能阻塞等待结果返回,如果有大量查询同时并发请求,那么后面的请求都需要等待前面的请求执行完成后才能开始执行。因此有时候从应用程序的日志看,有些 SQL 执行了几分钟,但将 SQL 单独拎出来执行却只有几毫秒的情况。对于这种情况,实际上就是因为这些 SQL 语句在等待前面的 SQL 执行完成。

那么这个问题该如何解决呢?其实多建立一些连接就可以解决这个问题,多建一些连接目的是让请求能够并发执行,从而使后面的连接不需要等待那么久。但需要注意的是,连接数过小的问题受数据库和客户端两侧同时限制。

  • 数据库连接数过小的情况:

    MySQL 的最大连接数默认是100,最大可以达到 16384,可以通过如下命令将 SQL 的最大连接数改为500。

    sql 复制代码
    SET GLOBAL max_connections = 500;

    查看 MySQL 最大连接数配置命令:

    sql 复制代码
    SHOW GLOBAL VARIABLES LIKE 'max_connections';
  • 应用侧连接数过小的情况:

    如果数据库连接大小是调整过了,但却没啥效果,那可能是因为服务应用(如 Java 或 Python 应用等)的连接数也过小。应用侧与 MySQL 底层的连接是基于 TCP 协议的长连接,而建立长连接比较耗时,所以通常情况下会维护一个长连接池,要执行 SQL 时从里面捞出一条连接出来用,用完塞回去,下次复用。

    需要注意的是,连接池的容量会有上限,连接池容量的上限指的是连接池能够控制的连接数量,如果连接池容量的上限太低,那么修改连接池最大连接数也没什么作用。

    如果需要调大这个连接池该如何调呢?在实际编码中,通常服务应用(如 Java 或 Python 应用等)都会通过 ORM 库进行读写操作,而成熟的 ORM 库会有个连接池的配置,按照官方文档改就好。

情况二:Buffer Pool 太小

Buffer Pool 太小也会导致 MySQL 查询慢的问题。在前文提到的 InnoDB 存储引擎中里有一层内存 Buffer Pool,Buffer Pool 通过缓存磁盘数据用于加速查询,如果 Buffer Pool 越大,那么 Buffer Pool 中能够存放的数据页就越多,相应的 SQL 查询时就更可能命中 Buffer Pool,那么 MySQL 查询速度自然更快。

可以执行下面命令增大 Buffer Pool 的大小:

sql 复制代码
SET GLOBAL innodb_buffer_pool_size = 536870912;

innodb_buffer_pool_size 是 MySQL 中用于设置 Buffer Pool 的参数,它的单位为字节。上例中,将 innodb_buffer_pool_size 的值设置为 536870912 即将将 InnoDB 缓冲池的大小为 536870912 字节,换算成兆字节(MB)为 521 MB(因为 1 MB = 1024 * 1024 个字节)。

查询 innodb_buffer_pool_size 的大小命令:

sql 复制代码
SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool_size';

输出的结果例如:

但是如果数据库查询慢并不是由于 Buffer Pool 的大小导致,那么修改 Buffer Pool 的大小就毫无意义。那么如何判断 Buffer Pool 是不是太小了?可以通过查看 Buffer Pool 的命中率来分析。

可以通过如下命令查询 Buffer Pool 的一些相关信息:

sql 复制代码
SHOW STATUS LIKE 'Innodb_buffer_pool_%';

得到的 Buffer Pool 相关信息例如:

其中 Innodb_buffer_pool_read_requests 表示请求的次数,Innodb_buffer_pool_reads 表示从物理磁盘中读数据的请求次数。

Buffer Pool 的命中率可以通过如下公式计算:

html 复制代码
1-(Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests)*100%

例如上述 Buffer Pool 的命中率为:

html 复制代码
1-(68759212/4966742025)*100% ≈ 98.6156%

一般情况下,Buffer Pool 的命中率都在 99% 以上,如果低于 99% 才需要考虑加大 Buffer Pool 的大小。

相关推荐
干啥都是小小白10 分钟前
话题通信之python实现
python·机器人·ros
不辉放弃26 分钟前
HiveSQL语法全解析与实战指南
数据库·hive·大数据开发
仟濹31 分钟前
「数据采集与网络爬虫(使用Python工具)」【数据分析全栈攻略:爬虫+处理+可视化+报告】
大数据·爬虫·python·数据挖掘·数据分析
水银嘻嘻1 小时前
03 APP 自动化-定位元素工具&元素定位
python·appium·自动化
Elastic 中国社区官方博客1 小时前
Elastic 和 AWS 合作将 GenAI 引入 DevOps、安全和搜索领域
大数据·数据库·elasticsearch·搜索引擎·云计算·全文检索·aws
蹦蹦跳跳真可爱5891 小时前
Python----目标检测(《用于精确目标检测和语义分割的丰富特征层次结构》和R-CNN)
人工智能·python·深度学习·神经网络·目标检测·cnn
我最厉害。,。1 小时前
接口安全&SOAP&OpenAPI&RESTful&分类特征导入&项目联动检测
后端·restful
20242817李臻1 小时前
李臻20242817_安全文件传输系统项目报告_第14周
数据库·安全
抽风的雨6102 小时前
【python深度学习】Day 42 Grad-CAM与Hook函数
开发语言·python·深度学习
MyikJ2 小时前
Java求职面试:从Spring到微服务的技术挑战
java·数据库·spring boot·spring cloud·微服务·orm·面试技巧