本章要回答的三个问题:一条 SQL 从文本到结果要经过哪些站,每一站可能出错或变慢的地方在哪?优化器拿着统计信息都做了什么决策,EXPLAIN 输出里藏着哪些信号?向量化执行和索引剪枝,各自把速度提升藏在了哪一步?
前两章备好了场地:内存管住了,数据摆好了。本章主角登场——查询引擎本身。这是"快"最终兑现的地方,也是排错时最需要看懂的地方:当一条查询出乎意料地慢,唯一的系统性路径是读懂它的执行计划,找到那个不合理的算子,然后用等价改写或布局调整把它治好。背优化口诀的人只能应付见过的题型,读懂计划的人能处理没见过的问题。
本章前四节按 SQL 的旅程顺序推进:流水线(路怎么走)、优化器(路怎么选)、向量化(每步怎么跑)、索引(哪些路可以不走)。第五节把四节知识拧成一次完整会诊——主线案例里那条按小时聚合的查询,在更复杂的业务问题面前慢到了四秒,我们把它压到八十毫秒。
读完本章,你应当能做五件事。第一,说清一条 SQL 经历解析、绑定、逻辑计划、优化、物理执行五个阶段,并指出常见报错各自发生在哪一站——语法错误在解析,列名写错在绑定,类型不匹配在计划。第二,读懂 EXPLAIN 与 EXPLAIN ANALYZE 的输出:估算行数与实际行数差几个量级说明统计过期,某个算子占比九成说明瓶颈就在它。第三,解释向量化为什么快:按列批量处理让解释开销摊薄、CPU 缓存命中率高、为并行与压缩感知执行打好基础。第四,利用 Zone Maps 与 ART 索引各自擅长的场景——前者靠数据布局自动剪枝,后者服务约束与点查。第五,独立完成一次慢查询会诊:从计划读出症结,用改写、布局、过滤前置三板斧把耗时压下来。第五条是前四条的验收考试——能独立会诊一条真实慢查询,才算真正走完了这一章。
时序图里值得盯住两个来回。优化器阶段有个自环——它在计划上反复做规则改写与代价比较,这是"同一查询可有多个等价计划"的体现;执行层与存储层之间是"按需取列段"的多次往返,取多少由过滤器决定,这正是第3章布局红利的兑现点。读时序图还有一个角度:把每个 participant 当成一个"可以出错的岗位"——文本写错是投稿人的问题,名字对不上是登记岗的问题,选路失真是参谋部的问题,算子跑崩是施工队的问题。岗位分清了,追责(排错)自然有序,这也是本章叫"一条SQL的旅程"而不是"优化器详解"的原因:旅程视角比部件视角更适合排错。
| 节号 | 回答哪个问题 | 关键产出 |
|---|---|---|
| 4.1 查询流水线 | SQL 经历哪几站 | 五段旅程图与报错定位法 |
| 4.2 优化器与执行计划 | 优化器在决策什么 | EXPLAIN 读懂执行计划的方法 |
| 4.3 向量化执行 | 一次处理一批好在哪 | 向量化收益的三层解释 |
| 4.4 索引机制 | 列存引擎的索引长什么样 | Zone Maps 与 ART 分工表 |
| 4.5 慢查询会诊实录 | 理论如何拧成一次实战 | 四秒到八十毫秒的完整过程 |
需要第3章的行组、列段、统计概念(剪枝全靠它们),以及第2章的并行常识。SQL 层面要求不变:会读 JOIN 与子查询即可,看不懂的函数现场查。
建议给本章留出"动手读计划"的时间——四、五两节的内容不亲手看一次 EXPLAIN 输出,读起来像背地图;亲手看过一遍自己的查询计划,再回读正文会快很多。各节之间还有一条暗线值得留意:优化器做决策的依据(统计信息)来自第3章的段头,优化的结果(下推、剪枝)兑现于第3章的布局——所以第3章学得越扎实,本章的每一步都越眼熟。读到第五节会诊实录时,前面所有伏笔会同时收线。
本章之后,"让单条查询变快"的工具箱就齐了。下一章视角外移:查询引擎怎么被各种语言与工具驱动,结果集怎么零拷贝地流进 Python 与 BI。第7章则会把本章的会诊方法沉淀成一份调优清单——到那时你会发现自己已经能做半个性能工程师。