Microsoft SQL Server 2012 Internals 把 SQL 语句的处理分为四个阶段,分别是 解析、绑定、优化、执行,如图所示:
解析(Parse)主要是语法分析,比较简单。绑定(Bind),书中的解释比较简略:
For queries with valid SQL syntax, the next stage performs a series of validation steps on the query, generally called binding, where the columns and tables in the tree are compared to database metadata to ensure that those columns and tables exist and are visible to the current user. This stage also performs semantic checks on the query to ensure that it's valid, such as making sure that the columns bound to a GROUP BY operation are valid.
(要是查询的语法正确,那么下一步则是针对该查询做一系列的验证,统称为绑定(binding),树中的列和表要与数据库元数据比对,确保这些列和表在数据库中是存在的,且对当前用户可见。这个阶段也要做一些语义检查,以确保查询在语义上的合法性,譬如,检查 GROUP BY 列的合法性。)
两句话,说明了这个阶段的两项主要工作:绑定(可以认为是变量合法性检查)和语义检查。解析主要做语法检查,这个阶段加入了语义检查。语法与语义检查的区别可以用一个例子说明:
USE AdventureWorks2012
GO
SELECT MakeFlag, SUM(ListPrice)
FROM Production.Product
GROUP BY ProductNumber
按 Ctrl + F5 做语法检查,显示 命令已成功完成,表示该查询再语法上没有错误。按 F5 执行,则显示如下错误信息:
消息 8120,级别 16,状态 1,第 1 行
选择列表中的列 'Production.Product.MakeFlag' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。
说明此查询在语义上有错误。
这个阶段虽然被称为绑定(Bind),但并不是正式名称,其正式名称在 SQL Server 2000 以前称为 Normalizer,而在 SQL Server 2005 以后改为 Algebrizer。由于技术保密,这本 Internals 书没有透露更多信息,甚至都没有 Algebrizer 这个名字,只笼统以 Bind 名之。
SQL Server 2014 Development Essentials 一书关于 Algebrizer 给出了更多信息:
If the query syntax is valid, the command parser generates a parse tree and proceeds to the algebrizer. The algebrizer's primary function is to perform binding, that is, to validate whether the tables and columns used in the query exist; load the metadata information for the tables and columns; identify all of the data types used for the query; add information about the required implicit data conversions (typecasting) to the algebrizer tree; replace views with definitions; verify whether the GROUP BY and aggregate functions are used in the right place; and perform simple, syntax-based optimizations.
(如果查询的语法正确,则命令解析器为该查询生成语法树并将其传递给 algebrizer。Algebrizer 的主要作用:绑定,也就是说,验证查询中用到的表与列是否存在;加载这些表和列的元数据;识别查询中所有的数据类型;为 algebrizer 树中所需要的隐式数据转换(类型转换)添加必要的信息;对查询中所有的视图,用其定义替换;核实 GROUP BY 以及聚集函数的使用是否得当;并执行一些简单的基于语法的优化。)
这段对 algebrizer 的描述更为具体。从这段描述中,我们是否可以合理地猜测 algebrizer = algebra + optimizer?如果此猜测成立,则 algebrizer 可以译为 代数优化器。
Microsoft SQL Server 的工程师 HarshDeep Singh 写了一篇文章 An in-depth look at SQL Server Memory ,其中有关于 Algebrizer Trees 的内容:
The query optimizer does not directly act on raw query text; it needes a more structured input. The Algebrizer's job is to produce an algebrizer tree, which represents the logical structure of a query. As part of this process, the Algebrizer performs tasks like resolving table, column, and variable names to particular objects in the database. It also determines the data types of any expressions in the query. Since we have the compiled plans, we do not need to cache Algebrizer trees.
(查询优化器并不直接在查询的原始文本上工作,它需要一个更加结构化的输入。Algebrizer 的任务就是产生 algebrizer tree,这棵树表示了查询的逻辑结构。作为其工作的一部分,Algebrizer 还要做一些诸如将表、列、及变量名解析到数据库中特定对象的工作。确定查询表达式的数据类型也是 Algebrizer 的事。因为我们有编译后的执行计划,所以不需要缓存 Algebrizer 树。)