{"name":"查询优化","id":"中间件-数据库-mysql-查询优化","content":"# 查询优化\n\n## 一、查询优化的第一性原理（原理层 · 稳定）\n\n### 1.1 查询性能的本质公式\n\n> **查询性能 ≠ SQL 执行速度**\n> **查询性能 = 数据访问成本 + 计算成本 + 协调成本**\n\n这是所有数据库、所有版本、所有引擎都成立的**第一性原理**。\n\n| 成本类型   | 本质解释      | 常见表现          |\n| ------ | --------- | ------------- |\n| 数据访问成本 | 访问了多少数据   | 扫描行数、回表、随机 IO |\n| 计算成本   | 对数据做了多少处理 | 排序、聚合、表达式计算   |\n| 协调成本   | 多对象协作的代价  | 锁等待、JOIN、中间结果 |\n\n**查询优化的全部目标：**\n👉 用尽可能低的代价，得到足够准确的结果。\n\n---\n\n### 1.2 一个更底层的不变量\n\n> **性能问题，本质是“无效数据的代价”**\n\n* 扫描但未返回的数据\n* 排序但最终被丢弃的数据\n* JOIN 过程中生成但未使用的中间结果\n* 为分页而遍历的历史数据\n\n**优化 ≠ 更快执行**\n**优化 = 更少做无意义的工作**\n\n---\n\n## 二、查询优化的三层认知模型（结构层 · 稳定）\n\n```\n查询优化\n├── 逻辑层：你“想要什么”\n├── 执行层：数据库“如何做”\n└── 物理层：数据“如何存”\n```\n\n这是理解所有优化手段的**认知骨架**。\n\n---\n\n## 三、逻辑层优化：减少“想要的东西”（抽象层）\n\n### 3.1 结果集裁剪原则（最重要）\n\n> **越早裁剪，越低成本**\n\n| 裁剪方式 | 原理           |\n| ---- | ------------ |\n| 列裁剪  | 减少数据传输与内存占用  |\n| 行裁剪  | 减少扫描、排序、JOIN |\n| 条件前推 | 减少中间结果规模     |\n\n**设计原则：**\n\n* SELECT 只返回必要字段\n* WHERE 越精确越好\n* LIMIT 是一种“成本控制器”\n\n---\n\n### 3.2 大查询拆分原则\n\n> **不要一次性处理峰值负载**\n\n将一个“资源洪峰”拆解为多个“小波峰”：\n\n* 降低锁冲突\n* 平滑 IO 压力\n* 提高系统整体可预测性\n\n👉 本质是 **时间换空间、稳定性换复杂度**\n\n---\n\n## 四、执行层优化：减少“如何做”的成本（架构层）\n\n### 4.1 MySQL 执行架构（稳定认知）\n\n```\nSQL\n → 解析（Parser）\n → 预处理（Preprocessor）\n → 优化（Optimizer）\n → 执行（Executor）\n → 存储引擎（Storage Engine）\n```\n\n**关键认知：**\n\n* 优化器是**基于统计假设的成本计算器**\n* 执行引擎只是“计划的执行者”\n* 存储引擎决定 IO 行为\n\n---\n\n### 4.2 扫描行数：执行层最重要指标\n\n> **扫描行数 ≫ 返回行数 = 性能风险**\n\n衡量手段：\n\n* 慢查询日志（rows_examined）\n* EXPLAIN 预估行数\n\n**理想状态：**\n\n```\n扫描行数 ≈ 返回行数\n```\n\n---\n\n### 4.3 覆盖索引的本质\n\n> **避免回表 = 避免随机 IO**\n\n覆盖索引不是“技巧”，而是一种**执行路径优化**：\n\n* 索引即数据\n* 在有序结构中完成计算\n* 减少存储层交互\n\n---\n\n### 4.4 JOIN 的本质代价\n\n> **JOIN 是中间结果放大器**\n\nJOIN 的真实成本来自：\n\n* 驱动顺序\n* 中间结果规模\n* 条件是否可下推\n\n**设计原则：**\n\n* 小表驱动大表\n* JOIN 条件必须可索引\n* 能拆就拆，能缓存就缓存\n\n---\n\n## 五、物理层优化：减少“数据如何存”的摩擦（实现层）\n\n### 5.1 排序的真实成本模型\n\n> **排序不是比较，而是搬运数据**\n\n* filesort ≠ 文件排序\n* 临时表 ≠ 内存安全\n\n排序代价由三部分构成：\n\n1. 数据量\n2. 数据宽度\n3. 临时空间\n\n**核心原则：**\n\n* 利用索引的有序性\n* 用 LIMIT 控制排序规模\n\n---\n\n### 5.2 临时表与内存边界\n\n> **所有“内存操作”都有溢出成本**\n\n* 内存临时表 → 磁盘临时表\n* 小参数 → 多次 IO\n* 大参数 → 内存竞争\n\n👉 本质是 **资源配额管理问题**\n\n---\n\n## 六、优化器：能力、边界与理性使用（哲学层）\n\n### 6.1 优化器的工作假设\n\n优化器依赖：\n\n* 统计信息\n* 基数估算\n* 成本模型\n\n但它**不知道业务真实分布**。\n\n---\n\n### 6.2 为什么不要迷信优化器提示\n\n> **Hint 是“冻结假设”**\n\n* 数据会变\n* MySQL 会演进\n* 旧假设可能变成性能陷阱\n\n**设计哲学：**\n\n> 只有在“结构性误判”时，才干预优化器\n\n---\n\n## 七、典型查询模式的本质分析（模式层）\n\n### 7.1 COUNT 的哲学\n\n> **COUNT 的成本 = 遍历成本**\n\n* COUNT(*) ≠ 免费\n* 精确统计是昂贵操作\n\n**架构性解法：**\n\n* 汇总表\n* 近似值\n* 外部缓存\n\n---\n\n### 7.2 分页的核心矛盾\n\n> **OFFSET 的本质是“丢弃成本”**\n\n* OFFSET 越大，丢弃越多\n* 本质是线性扫描\n\n**正确思路：**\n\n* 基于游标\n* 基于边界值\n* 基于连续性假设\n\n---\n\n### 7.3 IN / 子查询的风险本质\n\n> **优化器无法准确评估“组合爆炸”**\n\n* IN 参数过多\n* 子查询结果集不确定\n\n👉 本质是 **估算失败导致路径错误**\n\n---\n\n## 八、查询优化的决策框架（方法论）\n\n```\n查询慢\n├─ 数据访问多？\n│   ├─ 索引设计\n│   ├─ 条件裁剪\n│   └─ 数据分布\n├─ 中间结果大？\n│   ├─ JOIN\n│   ├─ 排序\n│   └─ 分组\n├─ 协调成本高？\n│   ├─ 锁\n│   ├─ 事务\n│   └─ 网络\n└─ 架构问题？\n    ├─ 缓存\n    ├─ 汇总\n    └─ 异步\n```\n\n---\n\n## 九、演进视角：哪些知识会过期，哪些不会\n\n### 会过期的\n\n* 参数调优经验\n* 某版本优化器缺陷\n* 特定 Hint 用法\n\n### 不会过期的\n\n* 减少扫描行数\n* 减少中间结果\n* 提前裁剪数据\n* 用结构换性能\n\n## 关联内容（自动生成）\n\n- [/中间件/数据库/数据库优化.md](/中间件/数据库/数据库优化.md) 数据库优化涵盖更广泛的优化策略，包括索引模型、查询优化、分布式治理等，与MySQL查询优化形成互补\n- [/中间件/数据库/索引.md](/中间件/数据库/索引.md) 索引技术是查询优化的核心基础，详细介绍了B+树、哈希索引等数据结构及优化策略\n- [/数据技术/检索技术.md](/数据技术/检索技术.md) 检索技术与查询优化在索引结构、查询性能优化方面有诸多相通之处\n- [/中间件/数据库/ElasticSearch.md](/中间件/数据库/ElasticSearch.md) ES的查询优化与MySQL查询优化在性能调优、索引策略等方面可作对比参考\n- [/数据技术/数据建模.md](/数据技术/数据建模.md) 数据建模中的物理优化能力与查询优化密切相关，涉及索引、分区等策略\n- [/中间件/数据库/PostgreSQL.md](/中间件/数据库/PostgreSQL.md) PostgreSQL的查询优化策略与MySQL可作对比学习，加深对数据库优化原理的理解\n- [/软件工程/架构/系统设计/缓存.md](/软件工程/架构/系统设计/缓存.md) 缓存策略是查询优化的重要组成部分，与数据库查询优化形成完整的数据访问优化体系\n- [/中间件/数据库/数据库系统/事务管理/事务.md](/中间件/数据库/数据库系统/事务管理/事务.md) 事务管理与查询优化密切相关，特别是在并发控制和锁策略方面\n\n","metadata":"tags: ['数据库', '性能', '索引优化', 'sql']","hasMoreCommit":true,"totalCommits":21,"commitList":[{"date":"2026-05-27T10:08:04+08:00","author":"MY","message":"doc(性能工程): 重构文档","hash":"2e3648b1dc0bf9be8e1790389811bdd99e878f29"},{"date":"2026-02-28T15:03:54+08:00","author":"MY","message":"docs(java): 移除JDBC相关文档链接并优化ORM章节结构","hash":"ec18590f8db79888521ec0118110d5a50e935b87"},{"date":"2026-02-12T14:07:03+08:00","author":"MY","message":"doc: 整理标签","hash":"290b3e8ad18f48832ac282290238d020fc030a88"},{"date":"2026-01-13T14:37:48+08:00","author":"MY","message":"docs(database): 完善MySQL查询优化文档内容","hash":"657d83607f469c1a257dfa35f747a55538074898"},{"date":"2024-12-11T19:59:57+08:00","author":"MY","message":"📦MySQL","hash":"5c96cf53bb2f2ca8359f5fab16cf12f5ef224bbc"},{"date":"2024-12-04T19:02:28+08:00","author":"MY","message":"📦查询优化","hash":"4062d3668ce503f77c8033fb739d35c5f502e5f2"},{"date":"2024-11-07T16:23:04+08:00","author":"MY","message":"📦MySQL","hash":"cc0b244f98955ea55043ef57b13e9fe490a110b1"},{"date":"2023-04-13T16:14:49+08:00","author":"MY","message":"✏查询优化","hash":"48df8a71bd609a6f3484ba69bc82ce95f7977cc7"},{"date":"2023-04-11T17:13:09+08:00","author":"MY","message":"✏数据库","hash":"d33ed8bd57e31e17cc53d6f437689f46ba2160d3"},{"date":"2023-04-02T17:37:16+08:00","author":"MY","message":"✏️查询优化","hash":"07982618dc101a712dab3ea010a8db171878e686"}],"createTime":"2020-08-02T15:02:15+08:00"}