一文彻底弄懂MySQL的优化
在企业级 Web 开发中,MySQL 优化是至关重要的,它直接影响系统的响应速度、可扩展性和整体性能。下面从不同角度,列出详细的 MySQL 优化技巧,涵盖查询优化、索引设计、表结构设计、配置调整等方面。
一、查询优化
1. 合理使用索引
- 单列索引:为查询频繁的字段(如
WHERE
、ORDER BY
、GROUP BY
中的字段)创建单列索引。 - 组合索引:对于涉及多列条件的查询,建议使用组合索引。注意组合索引的顺序(最左前缀匹配原则)。
- 覆盖索引:确保查询的字段全部被索引覆盖,这样 MySQL 可以直接从索引中获取数据,而无需访问表数据。
- 避免过度索引:过多的索引会增加写操作的开销,如
INSERT
、UPDATE
和DELETE
操作,因为每次都要维护索引。
2. 优化查询语句
- 避免使用
SELECT \*
:明确选择需要的字段,避免多余的字段查询,减小数据传输量。 - 避免在
WHERE
条件中对字段进行函数操作:如WHERE YEAR(date_column) = 2023
,这种操作会使索引失效,改为WHERE date_column >= '2023-01-01' AND date_column < '2024-01-01'
。 - 避免在
WHERE
条件中使用OR
:OR
会导致全表扫描,尽量使用IN
或分解查询。 - 尽量减少子查询:使用
JOIN
替代子查询。子查询会在嵌套时频繁执行,每次可能都会导致重新扫描表。 - 合理使用
JOIN
:如果有多表关联查询,确保关联的字段有索引,且表连接顺序要优化(小表驱动大表)。
3. 分页查询优化
- 大数据分页:对于数据量非常大的分页查询,可以避免
LIMIT offset
方式,而是通过索引定位起始位置,例如WHERE id > last_seen_id LIMIT 10
。 - 减少数据扫描量:分页时不要
SELECT *
,只选择主键字段返回结果后再根据主键查询详细信息。
4. 合理使用临时表和缓存
- 复杂查询:对于复杂查询,可以先查询并存储到临时表中,再进行进一步查询操作,减少重复计算。
- 缓存机制:在应用层或数据库层(如使用 Redis、Memcached)对频繁访问的数据做缓存,避免每次都查询数据库。
5. 避免死锁和锁等待
- 减少锁范围:尽量让锁的范围小(如只锁定必要的行),避免表锁的使用。
- 减少事务执行时间:事务越长,锁定的资源时间越长,容易导致锁等待甚至死锁。尽量减少事务中的查询或更新操作时间。
二、索引优化
1. 主键和唯一索引的合理使用
- 主键索引:选择唯一且不变的字段作为主键,尽量使用自增整数主键,避免使用长字符串主键。
- 唯一索引:在不允许重复值的字段上(如用户名、邮箱等)创建唯一索引,避免重复数据的插入。
2. 覆盖索引
- 减少回表操作:对于查询涉及的字段全部在索引中时,MySQL 可以直接通过索引返回结果,避免回表查询。
3. 前缀索引
- 长字符串字段的索引:对 VARCHAR 等长字符串类型字段建立索引时,可以使用前缀索引(如
CREATE INDEX idx_name ON users(name(10))
),通过截取前几位字符来节省索引空间。
4. 避免冗余索引
- 避免重复索引:例如已经有
(a, b)
组合索引时,不需要再单独给a
建索引。 - 索引维护:定期检查无用的索引(使用
SHOW INDEX FROM table_name
)并删除,减少索引维护的开销。
三、表结构设计优化
1. 合理的表字段设计
- 数据类型选择:选择最小且足够的字段类型。比如
INT(11)
占用 4 字节,如果值范围较小,可以使用TINYINT
(1 字节)、SMALLINT
(2 字节)来节省空间。 - 使用
VARCHAR
而非CHAR
:CHAR
为定长,存储固定长度字符会造成空间浪费,而VARCHAR
为变长,适合存储不确定长度的字符串。 - 避免使用 BLOB 和 TEXT 类型:大字段会造成性能问题,尽量将大文件或大数据放在文件系统中,数据库中仅存储文件路径。
2. 表分区
- 水平分表:当表数据量过大(如上亿条记录)时,可以将表进行水平拆分,比如按照时间、用户ID等进行分表,减小单个表的大小。
- 分区表:MySQL 提供表分区功能,可以根据数据范围将数据划分到不同的物理分区,优化大表查询性能。
3. 表规范化和反规范化
- 表规范化:将数据分离到多个表中,避免数据冗余。数据量少时,范式化设计更易于维护。
- 反规范化:当查询性能成为瓶颈时,可以考虑反规范化,增加冗余字段减少表的关联查询。
四、事务和锁机制优化
1. 减少锁竞争
- 行锁优先:尽量避免使用锁范围更大的表锁,MySQL 的 InnoDB 引擎支持行锁,保证并发性。
- 分批提交:批量操作数据时,可以将操作拆分成多个小批次提交,减少长时间锁持有。
2. 合理使用事务
- 尽量减少事务时间:事务应尽可能短,避免长时间持有锁,导致资源被其他事务等待。
- 事务隔离级别选择:根据业务需求选择合适的隔离级别,较高的隔离级别如
SERIALIZABLE
会有更多的锁定开销,常用的是REPEATABLE READ
。
3. 使用乐观锁
- 应用层乐观锁:对于并发更新的业务场景,可以在应用层使用版本号控制(乐观锁)来避免锁冲突。
五、配置优化
1. 调整 InnoDB Buffer Pool
Buffer Pool 的大小:InnoDB 的 Buffer Pool 用于缓存数据和索引,配置合理的缓存大小是优化 MySQL 性能的关键之一。建议 Buffer Pool 设置为物理内存的 70-80%。
innodb_buffer_pool_size = 4G # 根据内存大小调整
2. 查询缓存(Query Cache)
关闭查询缓存:在 MySQL 5.7 及以后的版本,查询缓存功能逐渐被弃用,因为它在高并发场景下容易成为瓶颈。因此,建议将其关闭。
query_cache_type = 0
3. 线程池优化
调整连接线程:对于高并发的业务场景,可以调整 MySQL 的最大连接数(
max_connections
)和每个连接线程的最大数量。max_connections = 500
4. 磁盘 I/O 优化
调整 innodb_flush_log_at_trx_commit:
innodb_flush_log_at_trx_commit
控制日志何时写入磁盘。设置为2
时,可以降低磁盘 I/O,提升性能,但会稍微增加数据丢失的风险。innodb_flush_log_at_trx_commit = 2
5. 调整日志文件大小
设置合适的 redo log 大小:
innodb_log_file_size
配置 redo log 文件大小,建议根据写操作的频率和磁盘情况设置适合的大小,过小的 redo log 会频繁触发检查点,影响性能。innodb_log_file_size = 512M
6. 调整连接超时
避免无效连接长时间占用:可以设置 MySQL 的连接超时参数,避免连接长时间闲置,造成资源浪费。
wait_timeout = 600
interactive_timeout = 600
六、监控与调优
1. 使用 EXPLAIN
分析查询
EXPLAIN
分析执行计划:通过EXPLAIN
命令分析查询的执行计划,检查是否使用索引、扫描的行数等,优化 SQL 查询。EXPLAIN SELECT * FROM users WHERE name = 'Alice';
2. 慢查询日志
开启慢查询日志:通过慢查询日志可以监控哪些查询执行时间过长,帮助定位性能瓶颈。
slow_query_log = 1
long_query_time = 2 # 设置为超过2秒的查询记录到日志
3. 数据库性能监控
- MySQL Enterprise Monitor 或其他监控工具:使用监控工具跟踪数据库的整体性能指标,如 CPU、I/O、内存使用情况、查询响应时间、锁等待等,便于及时发现问题。
七、总结
MySQL 的性能优化需要从多个层面进行综合考虑:查询优化、索引设计、表结构设计、事务控制、配置调优等。在企业级 Web 开发中,不同业务场景下的优化需求有所差异,通常需要结合业务的实际需求做出合适的权衡。通过持续监控与调优,可以让 MySQL 数据库在高并发、大数据量的场景中保持高效稳定的性能。
来不及拥抱清晨,就已经手握黄昏。曾经的我苦苦找寻这份答案,如今已工作8年,已经是30岁的程序员了。时光流逝,白驹过隙,留给八年前的自己的答案。
一文彻底弄懂MySQL的优化的更多相关文章
- 一本彻底搞懂MySQL索引优化EXPLAIN百科全书
1.MySQL逻辑架构 日常在CURD的过程中,都避免不了跟数据库打交道,大多数业务都离不开数据库表的设计和SQL的编写,那如何让你编写的SQL语句性能更优呢? 先来整体看下MySQL逻辑架构图: M ...
- 一文彻底搞懂MySQL分区
一个执着于技术的公众号 一.InnoDB逻辑存储结构 首先要先介绍一下InnoDB逻辑存储结构和区的概念,它的所有数据都被逻辑地存放在表空间,表空间又由段,区,页组成. 段 段就是上图的segment ...
- 超干货!为了让你彻底弄懂MySQL事务日志,我通宵肝出了这份图解!
还记得刚上研究生的时候,导师常挂在嘴边的一句话,"科研的基础不过就是数据而已."如今看来,无论是人文社科,还是自然科学,或许都可在一定程度上看作是数据的科学. 倘若剥开研究领域的外 ...
- 熬夜肝出5大点,18张图带你彻底弄懂MySQL事务日志
在当今社会,充斥着大量的数据.从众多APP上的账户资料到银行信用体系等个人档案,都离不开对大量数据的组织.存储和管理.而这,便是数据库存在的目的和价值.目前数据库的类型主要分为两种,一种是关系型数据库 ...
- 一文快速搞懂MySQL InnoDB事务ACID实现原理(转)
这一篇主要讲一下 InnoDB 中的事务到底是如何实现 ACID 的: 原子性(atomicity) 一致性(consistency) 隔离性(isolation) 持久性(durability) 隔 ...
- 一文彻底读懂MySQL事务的四大隔离级别
前言 之前分析一个死锁问题,发现自己对数据库隔离级别理解还不够清楚,所以趁着这几天假期,整理一下MySQL事务的四大隔离级别相关知识,希望对大家有帮助~ 事务 什么是事务? 事务,由一个有限的数据库操 ...
- 一文彻底弄懂cookie、session、token
前言 作为一个JAVA开发,之前有好几次出去面试,面试官都问我,JAVAWeb掌握的怎么样,我当时就不知道怎么回答,Web,日常开发中用的是什么?今天我们来说说JAVAWeb最应该掌握的三个内容. 发 ...
- 一文彻底弄懂this关键字用法
哈喽,大家好,我是指北君. 介绍完 native.static.final 关键字后,指北君再接再厉,接着为大家介绍另一个常用的关键字--this. this 也是Java中的一个关键字,在<J ...
- 1.mysql优化---优化入门之MySQL的优化介绍及执行步骤
优化到底优化什么? 优化,一直是面试最常问的一个问题.因为从优化的角度,优化的思路,完全可以看出一个人的技术积累.那么,关于系统优化,假设这么个场景,用户反映系统太卡(其实就是高并发),那么 ...
- [转帖]一文看懂mysql数据库本质及存储引擎innodb+myisam
一文看懂mysql数据库本质及存储引擎innodb+myisam https://www.toutiao.com/i6740201316745740807/ 原创 波波说运维 2019-09-29 0 ...
随机推荐
- deepin国产操作系统 nvidia-docker2 的安装
====================================== 平时偶尔使用deepin系统,突然有个 nvidia-docker 的程序需要运行,平时工作都是在用Ubuntu,所以对d ...
- CORDIC算法解释及FPGA实现(圆坐标系)
CORDIC算法解释及Verilog仿真(圆坐标系) CORDIC算法原理阐述 CORDIC(Coordinate Rotation Digital Computer)算法,即坐标旋转数字计算方法,是 ...
- Java——N以内累加求和
2024/07/15 1.题目 2.错误 3.分析 4.答案 1.题目 2.错误 import java.util.Scanner; public class Main { public static ...
- 出海浪头之上,共探CDN进化新支力
CDN技术自问世以来已超过20个年头,在云计算与AI深度融合的大趋势下,各行业实际业务需求已发生巨变,下一代CDN技术又将走向何方?8月16日,"抓住泛娱热趋,打通增长脉络--大浪淘沙之后的 ...
- 关于人工智能的思考,写在chatGPT爆火之时
今天是2023年3月22日,今天思维比较活跃,故作文一篇,以记录当下所想. 先是回家询问了未婚妻的想法,然后记录自己的想法. 未婚妻的想法: 1.在AI领域已经滞后于世界了.因为在墙头上看到过一个加拿 ...
- 【YashanDB知识库】存储过程报错snapshot too old
问题描述 20231127上午客户反馈绩效系统20231125.20231126出现2次YAS-02020 snapshot too old的问题,测试也有类似问题. 该过程是客户新增的存储过程,目的 ...
- elementUI的select下拉框增加checkbox选择框(可全选/取消)
elementUI的select下拉框增加checkbox选择框 一.实现效果 二.实现方法 1.组件代码如下: <div> <el-select ref="select& ...
- 鸿蒙应用开发:如何与组件库(Glide)衔接?
Android 发展到现在不仅提供了很多 API,还提供了很多第三方库.这降低了我们开发者的开发难度,提升了开发效率,让应用开发更加的简单高效.众所周知,HarmonyOS 除了提供 16000 ...
- 工具 – Vite
前言 一直想 try Vite, 但一直没有机会. 今天突然 Live Server IP Address 手机连不上...也不知道是 Bug 还是怎么回事儿. 总之 IIS IP Address 没 ...
- POJ-2385 Apple Catching(基础dp)
It is a little known fact that cows love apples. Farmer John has two apple trees (which are convenie ...