任何从事大型数据库工作的人都知道查询可能会变得非常慢。这通常是因为缺乏必要的索引,或者查询中某些因素阻止了数据库系统利用索引。选择正确的索引,以及正确的读取数据顺序,是区分一个查询花费 10 毫秒还是 5 秒的关键。
选择索引和连接顺序的过程被称为查询规划,其结果是一个查询计划,告诉数据库系统如何回答用户的查询。对于单表的简单查询,找到最佳查询计划通常是轻而易举的。但是,对于包含许多表和索引的大型查询,可能的选项会迅速达到数千甚至数百万种,而其中许多选项非常慢,因此规划器的任务是从所有可能中找到最佳查询计划。


查询规划如何工作

大多数人对编译器比查询规划器更熟悉,因此我们可以将查询规划器的工作与编译器的工作进行比较。
编译器是一个程序,它将用编程语言编写的源代码翻译成可以由计算机处理器执行的机器代码。查询规划器的工作与之类似,其输入是用 SQL(或其他数据库查询语言)编写的代码,其输出是一个查询计划,描述数据库系统如何使用索引以及按什么顺序访问表。
编译器和查询规划器通常经历以下阶段:词法分析和语法解析、语义分析、优化以及代码生成。下面我们逐一探讨这些阶段,并理解编译器与查询规划器之间的相似性与差异。


词法分析和语法解析

在词法分析和语法解析阶段,源代码会被分析并分解为一系列标记(tokens),例如关键字、操作符和标识符。词法分析器生成的标记序列会根据编程语言的规则进行正确性检查。这阶段通常会构建一个语法树,它是源代码结构的分层表示,最终输出一个抽象语法树(AST)。在这一阶段,编译器和查询规划器之间没有显著区别。
例如,以下 SQL 查询:

SELECT name, avg(salary) FROM employees JOIN salary_info ON id = empid

其抽象语法树可能如下图所示(删除了不必要的部分,例如大小写和空格):

什么是查询规划器?插图
抽象语法树示意图


这仍然是同一个查询,只不过它现在是一个树状数据结构,便于规划器进一步分析。


语义分析

语义分析是检查源代码语义的过程。在这个阶段,会检测词法分析或语法分析中无法发现的语义错误,例如类型不匹配或未定义的变量。
对于查询规划器,其工作几乎完全相同:代替搜索类和方法,它会绑定表和列。通过语义分析,数据结构会丰富信息,例如列所属的表、列和表达式的类型等。


优化

优化阶段会根据解析和语义分析收集的信息进行迭代改进。通常,这依赖于查询中间表示(Intermediate Representation, IR),其形式可能与输入语言不同,但更易于执行优化。
在这一步,查询规划器会采用多种算法和技术来确定执行查询的最优方法,包括选择有效的连接算法和排序算法以及合适的索引。它还会进行类似编译器的优化,例如常量折叠(将表达式重写为更易优化的等效形式)。
例如,Vitess 的查询规划器会对某些条件进行转换以更好利用索引: 初始条件:

WHERE (id = 5 AND name = 'Toto') OR (id = 5 AND name = 'Mumin')

优化后:

WHERE id = 5 AND (name = 'Toto' OR name = 'Mumin')

这一重写使得查询能够更有效地利用 id 上的索引。

为什么表访问顺序很重要?

假设我们需要连接三个表:A 与 B,B 与 C。可以选择先连接 A 和 B,然后将结果连接 C;或者反过来,先连接 B 和 C,再与 A 相结合。中间结果的大小会大大影响查询速度。如果 AxB 很大,与 C 的连接会非常慢,而如果从 BxC 开始且其结果较小,速度会快得多。这是一个路径优化问题。
以下是 TPC-H 查询 #8 中使用的表之间关系的示意图:

什么是查询规划器?插图1


规划器需要访问所有表,并在不同连接成本之间找到最优路径,这也解释了连接顺序为何如此重要。


Vitess 查询规划器中的优化

在 Vitess 中,查询计划部分在 SQL 代理层 VTGate 上执行,部分在独立的分片上执行。最重要的优化是尽可能将操作下推到 MySQL。例如,优先在 MySQL 中执行连接或过滤会比在 VTGate 层操作数据行快得多。
对于聚合操作,Vitess 的策略是将尽可能多的聚合操作下推到 MySQL,然后对其结果进行汇总。这一过程显著减少了网络调用次数。


代码生成

在代码生成阶段,编译器生成机器代码,而查询规划器生成查询计划,明确数据库引擎执行查询的具体步骤,例如索引扫描、连接算法和排序算法。


优秀查询规划器的重要性

查询规划器是数据库管理系统的核心组件,规划器开发者的工作对数据库系统来说至关重要。查询规划领域持续活跃于研究中,新的算法和技术不断被开发出来。一个优秀的查询规划器能够直接影响数据库的性能和效率,并为依赖这些数据库的组织和用户带来实际价值。



什么是查询规划器?插图2

关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台

除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接

本文链接:http://choupangxia.cn/2025/09/10/what-is-a-query-planner/