行业新闻
MySQL分析器与优化器
>>>>分析器
由词法扫描器与语法分析器构成
词法扫描器
1、MySQL实现自己的词法扫描器
2、人工实现信息编排以便优化器获取信息,自动生成代码无法做到
3、实现上下文关联的token意义解析
4、关键字列表symbols[]在sql/sql_lex.h,功能名称列表sql_functions[]在sql/sql_lex.h
5、所有关键词表gen_lex_hash(sql/gen_lex_hash.cc)
6、词法扫描器在sql/sql_lex.cc
7、词法分析器的入口yylex()(sql/sql_lex.cc),依赖GNU Bison库。
语法分析器
使用语法生成器GNU Bison库。想更好了解MySQL语法分析阶段或者修改MySQL语法,需要对Bison有更深入了解
MySQL规则定义在sql/sql_yacc.yy,Bison使用它生成sql/sql_yacc.cc,语法规则分析入口yyparse().
语法树
语法分析结果得出语法树,不难想象,复杂的语法结构需要一个足够复杂有效地结构体来存储执行SQL语句阶段所需要的一切信息。
语法树以类型LEX对象体现,该类型实际上结构体st_lex(sql/sql_lex.h)的同名。
该结构体中至关重要的两个成员变量:
enum_sql_command sql_command;
SELECT_LEX select_lex;
sql_command表示了当前SQL语句的类型,select、update、delete或者其他类型语句,mysql_execute_command()(sql/sql_parse.cc)
中根据语句类型来执行流程的处理函数。
select_lex属于结构体st_select_lex类型(sql/sql_lex.h),该结构体保存了查询语句相关联的多种细节信息,如where子句、涉及表、
涉及列、优化建议、对子查询的SELECT_LEX实例的交叉引用、ORDER BY/GROUP BY/HAVING表达式、以及其他细节。
st_select_lex类型的关键成员Item* where,保存了where子句树的根节点,优化器需要的大量信息都是从where子句中萃取。
Item结构具备一些以val_开头的函数,函数名称的其他部分依赖于函数的返回类型,如val_int()返回int类型。
优化器使用st_select_lex类型的where变量来构建对记录组合的过滤表达式,过滤表达式通过调用Item::val_int()来过滤结果,
如果返回1,说明该记录符合约束条件,否则该记录不符合会被丢弃。
如果优化器不对过滤表达式进行改进的话,那么表达式完全与where子句对应。
优化器重写表达式减少计算量、使用更好的索引值。
>>>>优化器
考虑A join B join C,并存在where子句情形
原生处理逻辑:组合A,B,C三表,每个组合再过滤where表达式,这种情况需要计算A*B*C种组合,耗时异常