SQL引擎子系统的工作原理

SQL引擎子系统负责将用户发送过来的SQL请求进行解析,语义检查,生成逻辑计划,经过一系列重写和优化,生成物理计划,交由计划执行器执行。
SQL语句分为两大类。一是数据操作语言,包括 select update insert delete.另一类是数据定义语言,用于维护数据字典,包括 create table create index drop table alert table。数据定义语言通常不经过查询处理器的优化阶段,直接由DBMS静态逻辑调用存储引擎。和数据字典管理处理。

查询解析

SQL请求第一步是语法解释,多数DBMS通过类 lex 和 yacc 等工具生成词法与文法解释器,检查 SQL语句的合法性,将SQL文本转化为抽象语法树,随后在抽象语法树上做语义检查,解决名字和引用的问题。例如,结合数据字典检查操作的表和字段是否存在,用户是否有权限操作。并将引用的对象名规范化。每个表名规范为"database".“schema”."tablename"的形式。所有检查通过后生成逻辑查询计划。逻辑查询计划。是由一系列逻辑操作符组成的树结构。逻辑查询计划并不具备直接执行的能力。他通常只是一些标记数据结构,用于携带必要的操作信息,以方便后续的优化,生成真正执行的执行计划。

查询重写

查询重写系查询优化的预备阶段。在保证查询语义不变的情况下,对原有的查询结构做等价变换。查询重写优化通常系在逻辑计划上进行。查询重写一般有如下工作要做:

1.视图展开。对 from 子句中的每个引用的视图,从 category 中读取定义。用这个视图引用的表和谓词条件替换视图,以及任何引用这个视图中的列替换为对应视图引用的表的列引用。
2.常量折叠。对于那些在编译时间里可以计算到结果的表达式,直接计算后重写。如 a > 3+8,重写为 a >11
3.谓词逻辑重写,对 where条件中的谓词进行重写。如 a < 12 and a > 100 表达式可以直接转换为 false,返回空结果集。或者做逻辑等价变换,如 not a < 100转换为 a >= 100。还有一些转换会引入新的谓词。如 t.a > 120 and t.a = tt.x,这里隐含 tt.x > 120 的条件,因此可以提前对 tt 表的数据进行过滤。
4.子查询展开。嵌套查询在优化阶段比较难以处理,所以重写阶段一般会将其重写为 join 形式。如 select * from t1 where id in (select id from t2)会用 join 来重写 select distinct t1.* from t1,t2 where t1.id =t2.id

对查询重写目的是为了减少不必要的操作,将查询规范化。便于后续的优化阶段处理。

查询优化

查要查询优化就是将之前生成并重写过的逻辑计划转化为一个可执行的物理计划。查询优化的目的是为了找出所有可能的计划中代价最低的计划。常见的查询优化器一般结合两种技术。一是基于规则。另一个是基于代价。
MySQL的查询优化是基于规则的,它完全基于启发规则,将所有filter,limit操作都尽可能往后推迟执行。在多表join时,基于基数估计,优先选择小的表。
查询优化的技术细节一般都非常复杂。这里暂时不能够分享太多。

查询执行

执行器采用火山模型,也叫迭代器模型。它是一个拉数据的模型,即每一个执行计划中的物理算子实现为一个迭代器,每个迭代器都有一个get_next_row()的方法,每次调用这个方法都会返回算子产生的一行数据。程序通过在物理执行计划的Root操作符循环调用get_next_row()方法,直到所有的数据拉取完毕。

你可能感兴趣的:(数据库,sql,数据库,java)