MySql的性能优化指的是在不影响系统能正确运行的前提下,运行速度更快,完成特定功能所需的时间更短。

我们可以通过某些有效的方法来提高 MySQL 数据库的性能:


优化方面
核心策略具体方法与示例
数据库设计平衡规范与效率
选择合适的数据类型
规范化: 消除冗余,保证数据一致性 (如:将用户地址拆分成独立表)。
反规范化: 减少JOIN,提升读性能 (如:在用户表中直接存储常用地址字段)。
使用 INT 而非 BIGINT; 使用 VARCHAR(100) 而非 TEXT,以节省空间并提升效率。
查询优化避免低效操作使用 EXPLAIN 分析执行计划,避免全表扫描。
避免 SELECT *, 仅查询所需字段。
使用 LIMIT 限制返回行数。
简化复杂操作减少不必要的 JOIN; 考虑在应用层进行数据聚合。
索引优化有效创建索引为高频查询条件(WHERE)、连接字段(JOIN)、排序字段(ORDER BY)创建索引。
使用复合索引匹配多列查询。
避免索引滥用避免为不常用或重复度低的列创建索引,以减少写操作开销。
使用覆盖索引 (索引包含所有查询字段) 避免回表,极大提升速度。
配置与硬件调整内存设置设置合理的 innodb_buffer_pool_size (通常为物理内存的70-80%),将热点数据缓存在内存中。
升级硬件基础设施使用 SSD硬盘 提升I/O速度; 增加内存容量; 升级CPU。
架构扩展数据分片分库分表: 对超大规模数据进行水平拆分(按范围或哈希)或垂直拆分(按业务模块),分散负载。
读写分离配置主从复制,主库处理写操作,多个从库处理读操作,并通过负载均衡分发请求。
日常维护定期清理与优化定期清理无用数据,缩减表体积。
定期执行 
OPTIMIZE TABLE 或 ANALYZE TABLE 来整理碎片和更新统计信息,帮助优化器选择最佳执行计划。


MySQL数据库的性能特质,在低负载环境下往往难以被准确评估和观测。其真正的性能瓶颈、扩展性以及稳定性,只有在长时间、高并发、大数据量的生产级负载下才会充分暴露。当数千甚至上万用户同时访问一个网站时,每个点击、每次浏览都意味着向MySQL数据库发起查询、插入或更新操作。如果数据库性能不佳,大量并发请求会迅速耗尽数据库连接池,导致新的用户请求被拒绝,出现“无法连接数据库”的错误。同时,频繁的写操作会造成严重的锁竞争,更新订单状态或库存时会发生阻塞,使系统陷入停滞。而最直接影响用户体验的是查询速度。如果用户搜索一个商品或查看个人订单需要等待超过2-3秒,几乎一半的人会选择离开。缓慢的查询响应会让页面加载变得卡顿,直接导致用户流失和交易失败。因此,在高并发场景下,数据库性能直接决定了网站能否正常运营和用户体验的好坏。

因此,系统性地提升MySQL数据库性能是一项多维度的工程任务,其核心目标在于精准定位系统瓶颈,并通过体系化的优化策略实现整体性能提升。这要求我们不仅需要优化数据库本身的软硬件配置和参数调优,更要从数据模型设计的源头确保架构合理性,从而在显著提升用户操作响应速度的同时,高效利用系统资源,以支撑更大规模的业务负荷。

具体而言,优化工作需根据实际负载类型针对性展开。若数据库负载以大量查询操作为主,则应将优化重点置于SQL语句层面,通过分析和重写高时间复杂度的查询、引入恰当的索引策略,来降低单次查询的资源消耗,从而提升整体吞吐量。所以我们需要找到效率低下的SQL。

我们可以通过以下两种方式精准定位效率低下的SQL:

1. 使用 SHOW STATUS 命令

数据库管理员可以通过执行 SHOW STATUS语句来获取 MySQL 数据库的一系列内部性能计数器和状态变量。

其语法形式如下:

SHOW STATUS LIKE 'value';

其中,value最主要的参数有:

类别变量名描述解读与用途
连接与线程Threads_connected当前打开的连接数。监控数据库负载和连接池大小是否合理。
Threads_running当前正在执行的连接数。如果持续接近 max_connections,说明服务器繁忙或存在瓶颈。
Threads_created服务器启动后为处理连接而创建的线程总数。如果值很大,表明应增大 thread_cache_size 以节省创建线程的开销。
Aborted_connects尝试连接到数据库失败的次数。可用于检查是否有网络问题或错误的连接参数。
Max_used_connections服务器启动后同时使用的最大连接数。用于指导 max_connections 的设置,应留有余量。
查询相关Questions服务器启动以来客户端发送给服务器的语句总数。监控数据库总的请求压力。
Queries服务器启动以来执行的语句总数(包括存储过程中的语句)。类似于 Questions,但计数范围更广。
Com_selectSELECT 语句的执行次数。了解读操作的频率。
Com_insertINSERT 语句的执行次数。了解写操作的频率。
Com_updateUPDATE 语句的执行次数。了解写操作的频率。
Com_deleteDELETE 语句的执行次数。了解写操作的频率。
Slow_queries执行时间超过 long_query_time 秒的查询数量。关键指标。值持续增长意味着有查询需要优化。
InnoDB 存储引擎Innodb_rows_read从InnoDB表中读取的行数。评估数据库的总读取量。
Innodb_rows_updatedInnoDB表中更新的行数。评估数据库的总写入量。
Innodb_rows_deletedInnoDB表中删除的行数。评估数据库的总写入量。
Innodb_rows_insertedInnoDB表中插入的行数。评估数据库的总写入量。
Innodb_buffer_pool_reads从物理磁盘读取页面的请求数。关键指标。值高说明缓冲池太小或查询未有效利用缓存。
Innodb_buffer_pool_read_requests向缓冲池发起的逻辑读请求数。与 ...reads 对比计算缓存命中率。
缓存与临时表Key_reads从磁盘物理读取MyISAM索引块的次数。对于MyISAM表,值高说明 key_buffer_size 设置太小。
Key_read_requests向MyISAM键缓存发起的读请求数。用于计算MyISAM键缓存命中率。
Created_tmp_disk_tables服务器创建磁盘临时表的次数。关键指标。值高意味着需要优化查询或增加 tmp_table_size
Created_tmp_tables服务器创建临时表的总次数(包括内存和磁盘)。用于计算磁盘临时表占比。
Qcache_hits查询缓存命中的次数。(注:MySQL 8.0已移除查询缓存) 用于评估查询缓存的效益。
Qcache_inserts被加入到查询缓存的查询数量。(注:MySQL 8.0已移除查询缓存)

举一个最简单的例子,当我们需要查询 MySQL 服务器的连接次数,我们可以这样操作:

进入到MySQL Command Line Client:

客户端命令控制行

输入:

SHOW STATUS LIKE 'Connections';

结果:

查询连接次数

意义:自从MySQL连接以来,一共尝试连接过12次.(提示:在默认界面第3行-Your MySQL connection id is 12-这里可以看到连接次数)


2. 使用慢查询日志

通过慢查询日志定位那些执行效率较低的 SQL 语句,然后针对慢查询语句进行表结构优化或者查询语句优化。

一个简单的例子教会你通过慢查询日志定位执行效率底的 SQL 语句:(以我的电脑为例)

2.1 开启慢查询日志 , 配置样例:

找到并复制这个路径:C:\ProgramData\MySQL\MySQL Server 8.0\my.ini(一般情况下都是这个路径 主要是找到配置文件my.ini)

然后管理员模式启动记事本进行修改

找到[mysqld]

2.2 修改参数(添加以下参数)

# 启用慢查询日志功能 (1=ON, 0=OFF)
slow_query_log = 1
# 指定慢查询日志文件的存储路径和文件名
slow_query_log_file = /var/log/mysql/mysql-slow.log
# 定义“慢”的阈值,单位是秒。执行时间超过此值的SQL将被记录
long_query_time = 5
 # 通常先设置为5秒,根据实际情况调整

2.3 重启mysql

win+x 然后按A键进入PowerShell进行重启操作

PowerShell

2.4检查是否开启慢查询

输入:

SHOW VARIABLES LIKE 'slow_query_log';

结果:显示慢查询日志已打开

慢日志查询打开提示

3.1 临时修改时间阈值

输入:

SET SESSION long_query_time = 1;

结果:设置为1秒

3.2 执行一条慢的SQL

输入:

SELECT SLEEP(8);

结果:超过1秒 被记录

3.3 执行一条快的SQL

输入:

SELECT SLEEP(0.1);

结果:未超过1秒 不会被记录

各设置快慢查询操作一次

4.1 找到 C:\ProgramData\MySQL\MySQL Server 8.0\Data\DESKTOP-BO8KI50-slow.log

4.2 在慢查询日志里我们可以看到:

慢查询日志结果

解读:查询到我们超过1秒的SQL语句及其相关信息

点赞(2)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)