【Mysql】我在广州学Mysql 系列——Mysql 性能优化

news/2025/2/25 12:43:27

ℹ️大家好,我是练小杰,今天又是美好的星期一了,新的工作又要开始了,努力!!奋斗!!😆


本文是针对Mysql 性能优化>性能优化知识进行学习与讨论,后续将添加更多相关知识噢,谢谢各位的支持🙏

前情回顾: 【Mysql 日志管理详解】
数据库专栏:👉【数据库专栏】【Mysql练习题】

主页:👉【练小杰的CSDN】

申公豹:“人心中的成见是一座大山”

在这里插入图片描述

性能优化>性能优化

  • 主页:👉【[练小杰的CSDN](https://blog.csdn.net/weixin_55767624?spm=1011.2415.3001.5343)】
    • 申公豹:“人心中的成见是一座大山”
  • 理解性能优化>性能优化
    • MySQL优化的作用:
  • 优化查询
    • 索引对查询速度的影响
    • 分析查询语句
    • 使用索引查询
    • 优化子查询
  • 表结构优化
    • 选择合适的数据类型
    • 规范化与反规范化
    • 建立分区表
    • 分析表、检查表和优化表
  • 优化插入记录的速度
  • 配置优化
    • 调整缓冲区大小
    • 调整连接数
    • 启用查询缓存
  • 利用日志与监控
  • 优化MySQL服务器
    • 优化服务器硬件
    • 优化MySQL的参数
    • key_buffer_size 参数
    • table_cache 参数
    • query_cache_size 参数
    • 应用示例
  • 高级优化
    • 主从复制
    • 分库分表
  • 综合案例
    • 步骤1:分析查询语句,理解索引对查询速度的影响
    • 步骤2:练习分析表、检查表、优化表

在这里插入图片描述

理解性能优化>性能优化

  • 优化MySQL数据库数据库管理员和数据库开发人员的必备技能。
  • 通过合理的数据库设计、索引优化、查询优化、缓存优化、表结构优化、硬件和配置优化以及其他优化方法,可以显著提高 MySQL 数据库性能,确保其在高负载和高并发环境下的稳定性和高效性。

MySQL优化的作用:

一方面是找出系统的瓶颈,提高MySQL数据库整体的性能;另一方面,需要合理的结构设计和参数调整,以提高用户操作响应的速度;同时还要尽可能的节省系统资源,以便系统可以提供更大负荷的服务。

优化查询

索引对查询速度的影响

MySQL中提高性能的一个最有效的方式就是对数据表设计合理的索引
索引提供了高效访问数据的方法,并且可以加快查询的速度,因此,索引对查询的速度有着至关重要的影响。

sql">-- 创建索引
CREATE INDEX idx_name ON table_name(column_name);

-- 查看索引
SHOW INDEX FROM table_name;

-- 删除索引
DROP INDEX idx_name ON table_name;

分析查询语句

通过对查询语句的分析,可以了解查询语句执行情况,找出查询语句执行的瓶颈,从而优化查询语句。同时要避免全表扫描,确保查询条件使用索引。

  • 使用 EXPLAIN 分析查询语句
sql">EXPLAIN SELECT * FROM table_name WHERE condition;
//或者使用DESCRIBE语句
DESCRIBE SELECT select_options

⚠️注意: 留意type 列(其中ALL 表示全表扫描,refrange 表示使用索引),以及 rows 列(扫描的行数越少越好)。

  • 避免 SELECT *,优化中为 只选择需要的列
sql">SELECT column1, column2 FROM table_name;

使用索引查询

索引可以提高查询的速度。但并不是使用带有索引的字段查询时,索引都会起作用。

  • 使用LIKE关键字的查询语句

使用LIKE关键字进行模糊查询时,如果查询字段上有索引,索引会被利用,从而提高查询速度。如下,查询名字以“练”开头的所有用户。

sql">SELECT * FROM users WHERE name LIKE '练%';
  • 使用多列索引的查询语句

多列索引(复合索引)是指在多个列上创建的索引。当查询条件涉及到这些列时,索引会被利用,从而提高查询的效率。如下,查询年龄在20到30岁之间且姓名为“练小杰”的用户。

sql">SELECT * FROM users WHERE age BETWEEN 20 AND 30 AND name = '练小杰';

同时,为了优化上述查询,可以在 users 表上创建复合索引:

sql">CREATE INDEX idx_age_name ON users (age, name);
  • 使用OR关键字的查询语句

OR关键字连接多个条件时,如果涉及的字段上有索引,索引会被利用,从而提高查询速度。如下,查询年龄为25岁或姓名为“eason”的用户。

sql">SELECT * FROM users WHERE age = 25 OR name = 'eason';

优化子查询

  • 在MySQL中可以使用连接(JOIN)查询来替代子查询。
  • 连接查询不需要建立临时表,其速度比子查询要快,如果查询中使用到索引的话,性能会更好。连接之所以更有效率,是因为MySQL不需要在内存中创建临时表来完成查询工作。

表结构优化

选择合适的数据类型

使用最小的数据类型存储数据。例如,使用 TINYINT 代替 INT,使用 VARCHAR 代替 TEXT

规范化与反规范化

规范化: 减少数据冗余,提高数据一致性。
反规范化:合理地加入冗余数据减少连接操作,提高查询性能

建立分区表

将大表分成多个小表,提高查询效率。

sql">CREATE TABLE partitioned_table (
    id INT,
    created_at DATE
) PARTITION BY RANGE (YEAR(created_at)) (
    PARTITION p0 VALUES LESS THAN (2023),
    PARTITION p1 VALUES LESS THAN (2024),
    PARTITION p2 VALUES LESS THAN (2025)
);

分析表、检查表和优化表

  • MySQL提供了分析表、检查表和优化表的语句。
  1. 分析表:主要是分析关键字的分布。
  2. 检查表:主要是检查表是否存在错误。
  3. 优化表:主要是消除删除或者更新造成的空间浪费。

优化插入记录的速度

  • 影响插入速度的主要是索引、唯一性校验和一次插入记录条数等。根据这些情况,可以分别进行优化。

优化的方式:

  1. 禁用索引
  2. 禁用唯一性检查
  3. 使用批量插入
  4. 使用LOAD DATA INFILE 批量导入

配置优化

调整缓冲区大小

  • innodb_buffer_pool_size:InnoDB 缓冲池大小,建议设置为系统内存的 70%-80%。
sql">SET GLOBAL innodb_buffer_pool_size = 1G;
  • key_buffer_sizeMyISAM 键缓冲区大小。
sql">SET GLOBAL key_buffer_size = 512M;

调整连接数

  • max_connections:最大连接数。

    sql">SET GLOBAL max_connections = 500;
    
  • wait_timeout:连接空闲超时时间。

    sql">SET GLOBAL wait_timeout = 600;
    

启用查询缓存

  • query_cache_size:查询缓存大小。
    sql">SET GLOBAL query_cache_size = 64M;
    

利用日志与监控

慢查询日志

作用:记录执行时间超过指定阈值的查询。

sql">-- 启用慢查询日志
SET GLOBAL slow_query_log = 'ON';

-- 设置慢查询阈值(单位:秒)
SET GLOBAL long_query_time = 2;

-- 查看慢查询日志路径
SHOW VARIABLES LIKE 'slow_query_log_file';

性能监控

  • SHOW STATUS:查看服务器状态。
sql"> SHOW STATUS LIKE 'Threads_connected';
  • SHOW PROCESSLIST:查看当前连接和查询。
sql">SHOW PROCESSLIST;

优化MySQL服务器

优化服务器硬件

服务器的硬件性能直接决定着MySQL数据库性能。硬件的性能瓶颈,直接决定MySQL数据库的运行速度和效率。

  • 使用 SSD:因为 SSD 的读写速度远高于 HDD,适合高并发场景。

  • 增加内存: 增加内存可以提高缓冲区和缓存的效果。

  • 调整文件系统: 使用 XFSext4 文件系统,避免使用 ext3

优化MySQL的参数

通过优化MySQL的参数,可以提高资源利用率,从而达到提高MySQL服务器性能的目的。例如,下面的参数:

sql">key_buffer_size、table_cache、query_cache_size
……

key_buffer_size 参数

  • MySQL 中用于索引块的缓冲区大小。它主要用于 MyISAM 存储引擎,但也会影响 InnoDB 存储引擎的性能

  • 这个参数决定了 MySQL 用于缓存索引块的内存大小。较大的 key_buffer_size 可以存储更多的索引块,从而减少磁盘 I/O,提高查询性能

  • 调整方法:我们可以通过以下命令查看和设置:

sql">SHOW VARIABLES LIKE 'key_buffer_size';
SET GLOBAL key_buffer_size = 256M;

建议值:通常设置为服务器总内存的 25%30%,但具体值应根据实际工作负载进行调整。

table_cache 参数

  • table_cache(在 MySQL 5.1 及更高版本中称为 table_open_cache)是用于缓存打开的表文件的缓存大小。

  • 参数决定了 MySQL 可以缓存的打开表文件数量。较大的 table_cache 可以减少打开表文件时的磁盘 I/O,提高访问速度。同时,在高并发环境下,较大的表缓存可以提高并发处理能力,减少锁争用。

  • 配置建议:默认大小通常较小,建议根据服务器内存和并发连接数进行调整

sql">SHOW VARIABLES LIKE 'table_open_cache';
SET GLOBAL table_open_cache = 1024;

建议值:通常设置为并发连接数的 10 倍左右,但具体值应根据实际工作负载进行调整。

query_cache_size 参数

  • query_cache_size 是 MySQL 用于缓存查询结果的缓冲区大小。
  • 参数决定了 MySQL 用于缓存查询结果的内存大小。对于相同的查询,MySQL 可以直接从缓存中返回结果,避免重复执行查询,提高查询速度。
  • 作用:对于频繁执行的相同查询,较大的查询缓存可以显著提高响应速度。
  • 调整方法:
sql">SHOW VARIABLES LIKE 'query_cache_size';
SET GLOBAL query_cache_size = 128M;

建议值:通常设置为服务器总内存的 10% 到 20%,但具体值应根据实际查询负载进行调整。

应用示例

  • 假设有一台服务器,总内存为 8GB,可以考虑以下配置:
sql">SET GLOBAL key_buffer_size = 2G;
SET GLOBAL table_open_cache = 2048;
SET GLOBAL query_cache_size = 1G;

高级优化

主从复制

作用:通过主从复制分担读负载。
sql">-- 主服务器配置
SHOW MASTER STATUS;

-- 从服务器配置
CHANGE MASTER TO
    MASTER_HOST='master_host',
    MASTER_USER='replica_user',
    MASTER_PASSWORD='password',
    MASTER_LOG_FILE='sql>mysql-bin.000001',
    MASTER_LOG_POS=107;

分库分表

作用:将大表分成多个小表,或将数据分布到多个数据库中。
工具:MyCAT分布式数据库中间件,以及ShardingSphere分库分表解决方案。

综合案例

步骤1:分析查询语句,理解索引对查询速度的影响

  1. 使用分析查询语句“SELECT * FROM fruits WHERE f_name='banana';”,执行的语句及执行结果如下:
sql">EXPLAIN SELECT * FROM fruits WHERE f_name='banana';

在这里插入图片描述

  • 结果说明

type: const 表示这是一个常量查询,查询速度非常快。
key: idx_f_name 表示使用了 idx_f_name 索引。
rows: 1 表示只扫描了一行数据。
Extra: Using index 表示使用了覆盖索引,查询效率高。

  1. 使用分析查询语句“SELECT * FROM fruits WHERE f_name like '%na’”,执行的语句及执行结果如下:
sql">EXPLAIN SELECT * FROM fruits WHERE f_name like '%na';

在这里插入图片描述

  • 结果说明

type: ALL 表示这是一个全表扫描,查询效率低。
key: NULL 表示没有使用索引。
rows: 1000 表示扫描了1000行数据(假设表中有1000行数据)
Extra: Using where 表示需要使用 WHERE 子句进行过滤

⚠️ 使用 LIKE '%na' 时,查询条件以通配符 % 开头,MySQL 无法使用索引进行优化。

  1. 使用EXPLAIN分析查询语句下面执行“SELECT * FROM fruits WHERE f_name like 'ba%';”语句如下:
sql">EXPLAIN SELECT * FROM message WHERE title like ' ba%';

在这里插入图片描述

  • 结果说明

type: range 表示这是一个范围查询,查询效率较高。
key: idx_f_name 表示使用了 idx_f_name 索引。
rows: 50 表示扫描了50行数据(假设有50行数据符合条件)。
Extra: Using index 表示使用了覆盖索引,查询效率高。

步骤2:练习分析表、检查表、优化表

  1. 使用ANALYZE TABLE语句分析fruits表,执行的语句及结果如下:
sql">ANALYZE TABLE fruits;

在这里插入图片描述

  • 结果说明

Msg_text: Table is already up to date. 表示表已经是最新的,无需重新分析。
Msg_text: OK 表示分析操作成功完成。

  1. 使用CHECK TABLE语句检查表fruits,执行的语句及结果如下:
sql">CHECK TABLE fruits;

在这里插入图片描述

  • 结果说明

Msg_text: Table is marked as crashed and should be repaired. 表示表被标记为崩溃,需要修复。
Msg_text: Table 'fruits' is marked as crashed and should be repaired. 同样表示表被标记为崩溃,需要修复。

  • 修复方法及其修复结果
sql">REPAIR TABLE fruits;

在这里插入图片描述

Msg_text: OK 表示修复操作成功完成。
Msg_text: The repair has been completed. 表示修复操作已经完成。


本文有关Mysql数据库性能优化>性能优化内容已经讲完了, 明天再见啦👋
主页:【练小杰的CSDN】😆
ℹ️欢迎各位在评论区踊跃讨论,积极提出问题,解决困惑!!!
⚠️若博客里的内容有问题,欢迎指正,我会及时修改!!


http://www.niftyadmin.cn/n/5865513.html

相关文章

【DeepSeek-R1背后的技术】系列十一:RAG原理介绍和本地部署(DeepSeekR1+RAGFlow构建个人知识库)

【DeepSeek-R1背后的技术】系列博文: 第1篇:混合专家模型(MoE) 第2篇:大模型知识蒸馏(Knowledge Distillation) 第3篇:强化学习(Reinforcement Learning, RL)…

uniapp 微信小程序打包之后vendor.js 主包体积太大,解决办法,“subPackages“:true设置不生效

现在是打包的时候,vendor.js 的内容全部打到了主包里面, 说一下我的方法: 1. 通过发行 小程序打包 这样打包的体积是最小的,打包之后打开微信开发工具,然后再上传 2.manifest.json,在“mp-weixin”里添加代码 "…

OpenHarmony-4.基于dayu800 GPIO 实践(2)

基于dayu800 GPIO 进行开发 1.DAYU800开发板硬件接口 LicheePi 4A 板载 2x10pin 插针,其中有 16 个原生 IO,包括 6 个普通 IO,3 对串口,一个 SPI。TH1520 SOC 具有4个GPIO bank,每个bank最大有32个IO:  …

开源神器KRR:用数据驱动K8s资源优化

引言:云原生时代的资源管理之痛 在Kubernetes集群中,过度配置导致资源浪费与配置不足引发稳定性风险的矛盾始终存在。CNCF调研显示,企业平均有35%的云资源处于闲置状态。本文将揭秘开源神器KRR(Kubernetes Resource Recommender),通过数据驱动方式实现精准资源配置,实测…

详解Tomcat下载安装以及IDEA配置Tomcat(2023最新)

目录 步骤一:首先确认自己是否已经安装JDK步骤二:下载安装Tomcat步骤三:Tomcat配置环境变量步骤四:验证Tomcat配置是否成功步骤五:为IDEA配置Tomcat 步骤一:首先确认自己是否已经安装JDK jdk各版本通用安…

[java基础-JVM篇]1_JVM自动内存管理

JVM内存管理涉及但不限于类加载、对象分配、垃圾回收等,本篇主要记录运行时数据区域与对象相关内容。 内容主要来源《深入理解Java虚拟机:JVM高级特性与最佳实践》与官方文档,理解与表述错漏之处恳请各位大佬指正。 目录 运行时数据区域 栈 栈…

Flutter使用permission_handler请求通知权限不会弹出权限弹窗

Flutter中使用了 permission_handler 插件。 Permission.notification.request() 这样调用&#xff0c;来请求通知权限&#xff0c;怎么弄都不会弹出来权限弹窗。在iOS端上都是正常的。 解决办法&#xff1a; Future<void> sendTestNotification() async {FlutterLocal…

HarmonyOS NEXT通过关系型数据库实现数据的持久化

场景介绍 应用中&#xff0c;我们有些数据比较复杂&#xff0c;而且需要频繁的增删改查&#xff0c;这时候就不适合使用首选项来进行存储和管理了&#xff0c;HarmonyOS NEXT中的关系型数据库基于SQLite组件&#xff0c;适用于存储包含复杂关系数据。 基本概念 谓词&#xff…