移动云海山数据库(He3DB)-SQL语句执行流程(2)

1语法解析

1.1 bool do_command(THD *thd) 在sql_parse.cc中 该函数是由线程中的一个loop调用的,从连接中读取命令,执行命令。 “绝不能被递归调用”
image.png

1.2 get_command(&com_data, &command) 在sql_parse.cc中 获取package
image.png
调用protocol_classic.cc中 的 关键函数1:int Protocol_classic::read_packet() 读取数据包
image.png
调用protocol_classic.cc中 的 关键函数2: bool Protocol_classic::parse_packet(union COM_DATA *data, enum_server_command cmd) 数据的解析和校验
image.png
1.3 dispatch_command(thd, &com_data, command) 在sql_parse.cc中:处理一个connection级别的命令
image.png
thd->is_valid_time() 检验时间 <2038年 remove this when we have full 64 bit my_time_t support
image.png
password_expired() 检验密码是否有效
image.png
switch (command) 处理不同的command
image.png
在case COM_QUERY:中
image.png
关键调用函数:alloc_query() 在sql_parse.cc中: Read query from packet and store in thd->query.
image.png
关键调用函数:parser_state.init() 初始化
image.png
关键调用函数:mysql_parse(thd, &parser_state) 在sql_parse.cc中 Parse a query SQL语句的解析
image.png
关键调用函数:query_cache.send_result_to_client(thd, thd->query() 判断缓存是否命中,命中就直接返回
image.png
关键调用函数:parse_sql(),该函数是MYSQLparse()的包裹类。该类还会生成查询摘要query digest,可按照注释的方式调用之。
image.png
实际调用的函数:extern int MYSQLparse(class THD *thd); // from sql_yacc.cc 该函数实际调用了sql_yacc.cc文件中的函数:int MYSQLparse (class THD *YYTHD), 再实际调用yyparse (class THD *YYTHD)
image.png
关键调用函数:yylex(),根据宏定义实际调用的是MYSQLlex()函数,生成token
image.png
关键调用函数:mysql_execute_command(THD *thd, bool first_level) Execute command saved in thd and lex->sql_command.
image.png
image.png
在case SQLCOM_SELECT中,select_precheck() 检查权限
image.png
execute_sqlcom_select()执行它
image.png
调用函数:handle_query() 在sql_select.cc中Handle a data manipulation query, from preparation through cleanup
image.png
select_prepare() 在sql_resolver.cc中 Prepare query block for optimization. Resolve table and column information.
image.png
调用函数lock_tables() after preparation but before optimization 和 store_query() Register query result in cache
image.png
select->optimize(thd) 在sql_select.cc文件中
image.png
join->optimize() 在sql_optimizer.cc中 This is the entry point to the query optimization phase. This phase applies both logical (equivalent) query rewrites, cost-based join optimization, and rule-based access path selection. Once an optimal plan is found, the member function creates/initializes all structures needed for query execution.(对于优化器来说,所有的查询都是join) 和 unit->optimize() Optimize all query blocks of a query expression, including fake_select_lex
explain_query(thd, unit) 在sql_select.cc文件中 如果是explain语句,需要进入该分支执行 EXPLAIN handling for SELECT, INSERT/REPLACE SELECT, and multi-table UPDATE/DELETE queries
image.png
select->join->exec() 在sql_executor.cc中 Execute select, executor entry point.
image.png
JOIN::prepare_result() 在sql_select.cc中Prepare join result prior to join execution or describing. Instantiate derived tables派生表 and get schema tables 架构表 result if necessary.
image.png
do_select(JOIN *join) 在sql_executor.cc中 Make a join of all tables and write it on socket or to table
image.png

2.prepare sql_resolver.cc中

Query_bolck 和table、column的存储位置相绑定
2.1关键调用函数1:setup_tables() Set up table leaves in the query block based on list of tables 关联query block的tables。
image.png
2.2关键调用函数2: setup_wild() Expand all '’ in list of expressions with the matching column references 将""扩展为表上所有的列
image.png

2.3 关键调用函数 insert_fields() 在sql_base.cc中 Drops in all fields instead of current ‘*’ field 将展开后的item加入到item_list中

image.png
2.4关键调用函数3:setup_fields() 核心函数 Resolve a list of expressions and setup appropriate data

image.png
2.5关键调用函数:fix_fieleds(THD *thd, Item **ref) 在item.cc中 Functions to convert item to field (for send_result_set_metadata) 根据不同的resolution结果绑定一个item到field上。 该函数会在很多地方被调用,这是因为SQL Rewrite的过程中,列会发生变化(例如derive table、subquery),生成表的列优化为物理表的列。
image.png

2.6 关键调用函数4: setup_conds() Resolve WHERE condition and join conditions
image.png

2.7其他调用函数:setup_having、setup_group、setup_order、remove_redundant_subquery_clauses
关键调用函数:find_order_in_list() Resolve an ORDER BY or GROUP BY column reference. 也在内部调用了fix_fields()函数
image.png

3. do_select() sql_executor.cc中

Make a join of all tables and write it on socket or to table.

3.1通过join->first_select调用sub_select()函数 Retrieve 检索 records ends with a given beginning from the result of a join. 该函数有效地实现了嵌套循环联接算法的最后(n-k)个嵌套循环,其中k是join_tab表的序号,n是联接查询中表的总数。它执行嵌套循环连接,从where条件将所有连接谓词尽可能低地推送到表中。
image.png
关键调用函数 prepare scan() 准备好需要scan的表 it only materialized derived tables 派生表 and semi-joined subqueries 半连接子查询 and binds buffer for current rowid.
image.png
通过read_first_record调用joint_init_read_record() Prepare table for reading rows and read first record 具体化派生表、移除副本只保留tmp表、基于filesort存储表.
image.png
调用init_read_record() 在records.cc中 读取第一条记录、提供了多种set up的方式 rr_unpack_from_buffer、rr_from_pointers、rr_unpack_from_tempfile、rr_from_tempfile、rr_from_cache、rr_quick、rr_sequential
image.png
通过info->read_record(info)调用rr_sequential()函数 在records.cc中
image.png
调用函数ha_rnd_next() 在handler.cc中 读第一条记录 Read next row via random scan
image.png
调用函数ha_innobase::rnd_next(uchar* buf) 在 ha_innodb.cc中 此时要进入innodb层读取记录了
image.png
调用函数ha_innobase::index_first() 定位索引的第一条记录并读取到缓存中 Positions a cursor on the first record in an index and reads the corresponding row to buf.
image.png
调用函数ha_innobase::index_read()
image.png
调用函数row_search_mvcc() 在row0sel.cc中 Searches for rows in the database using cursor 用在通过连接共享的表中,因此也可以得到重构事务所需要的行。
image.png

4.存储引擎 入口函数row_search_mvcc

注释中详细介绍了一条select语句是如何执行的
image.png

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值