面试基础--MySQL SQL 优化深度解析
MySQL SQL 优化深度解析:EXPLAIN、索引优化与分库分表实践
引言
在互联网大厂的高并发场景下,数据库的性能优化是至关重要的。MySQL 作为最流行的关系型数据库之一,SQL 查询的性能直接影响了系统的响应时间和吞吐量。本文将深入探讨 MySQL 的 SQL 优化技术,包括 EXPLAIN 的使用、索引优化和分库分表策略,结合实际项目案例和源码分析,帮助读者深入理解 SQL 优化的实现原理。
1. SQL 优化的核心目标
SQL 优化的核心目标是减少查询的响应时间,提高系统的并发处理能力。具体目标包括:
- 减少磁盘 I/O:通过索引和缓存减少磁盘读取次数。
- 减少 CPU 消耗:通过优化查询逻辑减少 CPU 计算量。
- 减少锁竞争:通过合理的锁机制减少事务冲突。
2. EXPLAIN 的使用
EXPLAIN 是 MySQL 提供的用于分析查询执行计划的工具。通过 EXPLAIN,我们可以了解 MySQL 如何执行查询,从而发现性能瓶颈。
2.1 EXPLAIN 的输出字段
| 字段 | 描述 |
|---|---|
| id | 查询的标识符,表示查询的执行顺序。 |
| select_type | 查询的类型,如 SIMPLE、PRIMARY、SUBQUERY 等。 |
| table | 查询涉及的表。 |
| type | 访问类型,如 ALL、index、range、ref 等。 |
| possible_keys | 可能使用的索引。 |
| key | 实际使用的索引。 |
| key_len | 使用的索引长度。 |
| ref | 索引的引用列。 |
| rows | 估计需要扫描的行数。 |
| Extra | 额外的信息,如 Using where、Using index、Using filesort 等。 |
2.2 EXPLAIN 的使用示例
假设我们有一个订单表 orders,包含以下字段:
order_id:主键,自增。user_id:用户 ID。order_date:订单日期。amount:订单金额。
我们需要查询某个用户的所有订单:
EXPLAIN SELECT * FROM orders WHERE user_id = 123;
输出结果如下:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | orders | ref | idx_user_id | idx_user_id | 4 | const | 100 | Using where |
从执行计划可以看出,MySQL 使用了 idx_user_id 索引来查找数据,估计需要扫描 100 行。
2.3 EXPLAIN 的源码分析
EXPLAIN 的实现位于 sql/sql_explain.cc 文件中。以下是 EXPLAIN 的核心逻辑:
// sql_explain.cc 源码片段
bool Explain_query::explain_query() {// 解析查询语句Query_block *query_block = m_thd->lex->query_block;// 生成执行计划join->optimize();// 输出执行计划print_explain_output();return false;
}
3. 索引优化
索引是提高查询性能的关键。合理的索引设计可以显著减少查询的响应时间。
3.1 索引的类型
- 主键索引:唯一标识每条记录的索引。
- 唯一索引:保证索引列的值唯一。
- 普通索引:加速查询的普通索引。
- 联合索引:多个列组成的索引。
3.2 索引的设计原则
- 选择性高的列:选择性高的列更适合创建索引。
- 覆盖索引:索引包含查询所需的所有列,避免回表操作。
- 避免冗余索引:避免创建重复或冗余的索引。
3.3 索引的优化示例
假设我们需要查询某个用户在某个时间段的订单:
SELECT * FROM orders WHERE user_id = 123 AND order_date BETWEEN '2023-01-01' AND '2023-12-31';
我们可以为 user_id 和 order_date 创建联合索引:
CREATE INDEX idx_user_id_order_date ON orders (user_id, order_date);
通过 EXPLAIN 分析查询:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | orders | range | idx_user_id_order_date | idx_user_id_order_date | 8 | const | 50 | Using where |
从执行计划可以看出,MySQL 使用了联合索引 idx_user_id_order_date,估计需要扫描 50 行。
3.4 索引的源码分析
索引的实现位于 storage/innobase 目录下。以下是索引的核心数据结构:
- dict_index_t:索引的结构定义。
- btr0cur.cc:B+ 树游标的实现,负责遍历索引。
// dict_index_t 源码片段
struct dict_index_t {ulint type; // 索引类型ulint n_fields; // 索引字段数ulint n_unique; // 唯一索引字段数ulint stat_n_diff_key_vals[MAX_KEY]; // 索引的选择性
};
4. 分库分表
在高并发场景下,单库单表的性能可能无法满足需求。分库分表是解决这一问题的有效手段。
4.1 分库分表的策略
- 垂直分库:按业务模块将数据分布到不同的数据库。
- 水平分表:按某种规则将数据分布到多个表中。
4.2 分库分表的实现
假设我们有一个订单表 orders,包含 1 亿条数据。我们可以按 user_id 进行水平分表:
-- 创建分表 orders_0 到 orders_9
CREATE TABLE orders_0 (LIKE orders);
CREATE TABLE orders_1 (LIKE orders);
...
CREATE TABLE orders_9 (LIKE orders);
在查询时,根据 user_id 的哈希值选择对应的分表:
SELECT * FROM orders_{user_id % 10} WHERE user_id = 123;
4.3 分库分表的源码分析
分库分表的实现通常依赖于中间件,如 MyCat、ShardingSphere 等。以下是分库分表的核心逻辑:
// ShardingSphere 源码片段
public class ShardingRule {public String getActualTableName(String logicTableName, int shardingValue) {int tableIndex = shardingValue % 10;return logicTableName + "_" + tableIndex;}
}
5. 实际项目案例
5.1 项目背景
在一个电商平台的订单系统中,订单表 orders 包含 1 亿条数据。为了提高查询性能,我们需要进行 SQL 优化和分库分表。
5.2 SQL 优化
通过 EXPLAIN 分析查询,发现全表扫描的问题。我们为 user_id 和 order_date 创建联合索引,优化查询性能。
5.3 分库分表
按 user_id 进行水平分表,将数据分布到 10 个表中。通过中间件实现分表路由,提高查询性能。
5.4 性能对比
| 优化措施 | 查询响应时间(ms) | 磁盘 I/O(次) | CPU 消耗(%) |
|---|---|---|---|
| 无优化 | 1000 | 10000 | 80 |
| 索引优化 | 100 | 100 | 10 |
| 分库分表 | 50 | 50 | 5 |
6. 总结
MySQL 的 SQL 优化是提高系统性能的关键。通过 EXPLAIN 分析查询执行计划,合理设计索引,结合分库分表策略,可以显著提高查询性能和系统的并发处理能力。
在实际项目中,深入理解 SQL 优化的原理及其在 MySQL 中的实现,结合源码分析和实际案例,可以帮助我们更好地设计和优化数据库系统。
希望本文能为你在实际项目中优化 MySQL SQL 提供帮助。
参考文献:
- MySQL 官方文档
- InnoDB 存储引擎源码
- ShardingSphere 官方文档
相关文章:
面试基础--MySQL SQL 优化深度解析
MySQL SQL 优化深度解析:EXPLAIN、索引优化与分库分表实践 引言 在互联网大厂的高并发场景下,数据库的性能优化是至关重要的。MySQL 作为最流行的关系型数据库之一,SQL 查询的性能直接影响了系统的响应时间和吞吐量。本文将深入探讨 MySQL …...
python之爬虫入门实例
链家二手房数据抓取与Excel存储 目录 开发环境准备爬虫流程分析核心代码实现关键命令详解进阶优化方案注意事项与扩展 一、开发环境准备 1.1 必要组件安装 # 安装核心库 pip install requests beautifulsoup4 openpyxl pandas# 各库作用说明: - requests&#x…...
版本控制器Git和gdb
一.版本控制器Git 1.版本控制简单来讲可以对每一份代码版本进行复制保存,保证每一版代码都可查 2.仓库的本质也是一个文件夹 3.git既是一个客户端,也是一个服务器,是一个版本控制器。而gitee和GitHub都是基于git的网站或平台 4.git的基本…...
大白话面试前的准备工作
面试前的准备工作非常重要,就像打仗前要做好各种准备一样,主要包括以下几个方面: 了解公司和岗位 公司情况:要知道这个公司是做什么的,比如是生产电子产品的,还是提供互联网服务的。还要了解它在行业里的…...
Dify 开源大语言模型应用开发平台使用(一)
文章目录 一、创建锂电池专业知识解答应用1.1 应用初始化 二、核心功能模块详解2.1 知识库构建2.2 工作流与节点编排节点类型说明工作流设计示例:锂电池选型咨询 2.3 变量管理 三、测试与调试3.1 单元测试3.2 压力测试3.3 安全验证 四、部署与优化建议4.1 部署配置4…...
天津大学02-深度解读DeepSeek:部署、使用、安全【文末附下载链接】
大模型风险与不当用例——价值观错位 大模型与人类价值观、期望之间的不一致而导致的安全问题,包含:• 社会偏见(Social Bias)LLM在生成文本时强化对特定社会群体的刻板印象,例如将穆斯林与恐怖主义关联,或…...
SPI驱动(三) -- SPI设备树处理过程
文章目录 参考资料:一、SPI设备树节点构成二、SPI设备树示例2.1 SPI控制器节点属性2.2 SPI设备节点属性 三、SPI设备树处理过程四、总结 参考资料: 内核头文件:include\linux\spi\spi.h内核文档:Documentation\devicetree\bindin…...
【RAG 篇】万字长文:向量数据库选型指南 —— Milvus 与 FAISS/Pinecone/Weaviate 等工具深度对比
大家好,我是大 F,深耕AI算法十余年,互联网大厂技术岗。分享AI算法干货、技术心得。 欢迎关注《大模型理论和实战》、《DeepSeek技术解析和实战》,一起探索技术的无限可能! 文章目录 向量数据库的核心价值主流工具横向对比 FAISS:Meta 的高效检索引擎Pinecone:全托管商业…...
机器学习数学基础:40.结构方程模型(SEM)中卡方值与卡方自由度比
结构方程模型(SEM)中卡方值与卡方自由度比教程 在结构方程模型分析里,卡方值和卡方自由度比是评估模型拟合程度的重要指标,下面为大家详细介绍。 一、卡方值(CMIN) (一)基本概念与…...
MARL零样本协调之Fictitious Co-Play学习笔记
下列引用来自知乎作者Algernon 知乎link FCP作为ZSC领域两阶段训练方法的开创者 论文《Collaborating with Humans without Human Data》来自 NeurIPS 2021。这篇论文提出 Fictitious Co-Play (FCP) 来解决 ZSC 问题。论文认为,ZSC 的第一个重要问题是对称性&#x…...
idea中的查看git历史记录,不显示详细信息
一、正常情况显示 1、idea中git查看history正常显示如下图: 二、非正常情况下显示 1、idea中git查看history,现在不显示提交的历史文件详细信息,如下图: 三、解决方式 1、找到如下窗口中画红色框的黑色线条,鼠标放在…...
Redis——快速入门
目录 Redis简介 安装配置(Windows) GUI工具RedisInsight的使用 十大数据类型(5基本5高级) 字符串String 列表List 集合Set(S) 有序集合SortedSet(Z) 哈希Hash(H) 发布订阅模式 消息队列Stream(X) 地理空间Geospatial(GEO) HyperLogLog(PF) …...
LLM 模型 Prompt 工程
目录 1、Prompt 基础概念 2、Prompt 主要构成 3、Prompt 相关技术 3.1、思维链 3.2、自洽性 3.3、思维树 1、Prompt 基础概念 Prompt 工程是通过设计和优化自然语言提示(Prompt),引导LLM生成符合特定任务需求的输出的技术。其核心目标是…...
10个实用IntelliJ IDEA插件
精心整理了最新的面试资料和简历模板,有需要的可以自行获取 点击前往百度网盘获取 点击前往夸克网盘获取 以下是为提升开发效率推荐的10个实用IntelliJ IDEA插件,涵盖代码质量、效率工具及热门框架支持: 一、代码质量与规范 SonarLint 实时…...
Vue中实现大文件的切片并发下载和下载进度展示
Vue中实现大文件的切片下载 切片下载需要后端提供两个接口,第一个接口用来获取当前下载文件的总切片数,第二个接口用来获取具体某一个切片的内容。 界面展示 数据流展示 代码 接口 // 切片下载-获取文件的总切片数 export function getChunkDownload…...
开源表单、投票、测评平台部署教程
填鸭表单联合宝塔面板深度定制,自宝塔面板 9.2 版本开始,在宝塔面板-软件商店中可以一键部署填鸭表单系统。 简单操作即可拥有属于自己的表单问卷系统,快速赋能业务。即使小白用户也能轻松上手。 社区版体验地址:https://demo.tduckapp.com/home 前端项目地址: tduck-fro…...
GaussDB性能调优技术指南
一、性能调优核心目标 降低响应时间:缩短单次查询或事务的处理时间(如从秒级优化到毫秒级)。 提高吞吐量:支撑更高并发请求(如从千次/秒提升到百万次/秒)。 资源高效利用:减少 CPU、…...
【后端开发】go-zero微服务框架实践(goland框架对比,go-zero开发实践,文件上传问题优化等等)
【后端开发】go-zero微服务框架实践(goland框架对比,go-zero开发实践,文件上传问题优化等) 文章目录 1、go框架对比介绍2、go-zero 微服务开发实践3、go-zero 文件上传问题优化 1、go框架对比介绍 国内开源goland框架对比 1 go-…...
C#—csv文件格式操作实例【在winform表格中操作csv】
C#—csv文件格式操作实例【在winform表格中操作csv】 实例一 实例效果 当在winform界面中点击读取按钮时 将csv中的所有数据读取出来放置在datagridview控件,可以在datagridview控件中编辑数据,当点击保存按钮时 将datagridview控件中的所有数据存储在…...
一周学会Flask3 Python Web开发-WTForms表单验证
锋哥原创的Flask3 Python Web开发 Flask3视频教程: 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们可以通过WTForms表单类属性的validators属性来实现表单验证。 常用的WTForms验证器 验证器说明DataRequired(messageNo…...
23种设计模式一览【设计模式】
文章目录 前言一、创建型模式(Creational Patterns)二、结构型模式(Structural Patterns)三、行为型模式(Behavioral Patterns) 前言 设计模式是软件工程中用来解决特定问题的一组解决方案。它们是经过验证…...
GPIO及其应用
GPIO及其应用 文章目录 GPIO及其应用1.GPIO概括2.GPIO工作基本结构3.GPIO寄存器3.1寄存器总览3.2寄存器功能3.3BIT简写的代表 4.GPIO的电气特性4.1拉电流与灌电流4.2驱动大功率负载4.3电平逻辑兼容性 5.LED闪烁(实操)6.LED交替闪烁(实操)7.开关控制LED灯…...
NO1.C++语言基础|四种智能指针|内存分配情况|指针传擦和引用传参|const和static|c和c++的区别
1. 说⼀下你理解的 C 中的四种智能指针 智能指针的作用是管理指针,可以避免内存泄漏的发生。 智能指针就是一个类,当超出了类的作用域时,就会调用析构函数,这时就会自动释放资源。 所以智能指针作用的原理就是在函数结束时自动释…...
Vue 关于如何在vue中实现跨域请求问题
📚首先,让我们了解一下什么是跨域。当一个请求的URL的协议、域名、端口三者中任意一个与当前页面的URL不同,就称为跨域请求。 🔒为什么会出现跨域问题呢?这是因为浏览器的同源策略限制。同源策略是浏览器最核心的安全…...
毕业项目推荐:基于yolov8/yolov5/yolo11的暴力行为检测识别系统(python+卷积神经网络)
文章目录 概要一、整体资源介绍技术要点功能展示:功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出(xls格式)功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…...
算法随笔_64: 含特定字母的最小子序列
上一篇:算法随笔_63: 子数组范围和-CSDN博客 题目描述如下: 给你一个字符串 s ,一个整数 k ,一个字母 letter 以及另一个整数 repetition 。 返回 s 中长度为 k 且 字典序最小 的子序列,该子序列同时应满足字母 letter 出现 至少 repetitio…...
red hat系统离线部署Deepseek
一个人在单位离线部署踩了不少坑,记录一下 模型准备 1.huggingface下载gguf文件,将文件放到相应目录(例如E:/AI文件夹) 2.在文件夹内用文本建一个文件,命名Modelfile(删除txt后缀) 3.用文本编辑器打开Modelfile,在文本内输入 fr…...
torch.einsum 的 10 个常见用法详解以及多头注意力实现
torch.einsum 是 PyTorch 提供的一个高效的张量运算函数,能够用紧凑的 Einstein Summation 约定(Einstein Summation Convention, Einsum)描述复杂的张量操作,例如矩阵乘法、转置、内积、外积、批量矩阵乘法等。 1. 基本语法 tor…...
【DeepSeek】一文详解GRPO算法——为什么能减少大模型训练资源?
GRPO,一种新的强化学习方法,是DeepSeek R1使用到的训练方法。 今天的这篇博客文章,笔者会从零开始,层层递进地为各位介绍一种在强化学习中极具实用价值的技术——GRPO(Group Relative Policy Optimization)…...
C++基础系列【19】运算符重载
博主介绍:程序喵大人 35- 资深C/C/Rust/Android/iOS客户端开发10年大厂工作经验嵌入式/人工智能/自动驾驶/音视频/游戏开发入门级选手《C20高级编程》《C23高级编程》等多本书籍著译者更多原创精品文章,首发gzh,见文末👇…...
