函数代码

bool SELECT_LEX_UNIT::ExecuteIteratorQuery(THD *thd) {THD_STAGE_INFO(thd, stage_executing);DEBUG_SYNC(thd, "before_join_exec");Opt_trace_context *const trace = &thd->opt_trace;Opt_trace_object trace_wrapper(trace);Opt_trace_object trace_exec(trace, "join_execution");if (is_simple()) {trace_exec.add_select_number(first_select()->select_number);}Opt_trace_array trace_steps(trace, "steps");if (ClearForExecution(thd)) {return true;}mem_root_deque<Item *> *fields = get_field_list();Query_result *query_result = this->query_result();DBUG_ASSERT(query_result != nullptr);if (query_result->start_execution(thd)) return true;if (query_result->send_result_set_metadata(thd, *fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) {return true;}set_executed();// Hand over the query to the secondary engine if needed.if (first_select()->join->override_executor_func != nullptr) {thd->current_found_rows = 0;for (SELECT_LEX *select = first_select(); select != nullptr;select = select->next_select()) {if (select->join->override_executor_func(select->join)) {return true;}thd->current_found_rows += select->join->send_records;}const bool calc_found_rows =(first_select()->active_options() & OPTION_FOUND_ROWS);if (!calc_found_rows) {// This is for backwards compatibility reasons only;// we have documented that without SQL_CALC_FOUND_ROWS,// we return the actual number of rows returned.thd->current_found_rows =std::min(thd->current_found_rows, select_limit_cnt);}return query_result->send_eof(thd);}if (item) {item->reset_value_registration();if (item->assigned()) {item->assigned(false);  // Prepare for re-execution of this unititem->reset();}}// We need to accumulate in the first join's send_records as long as// we support SQL_CALC_FOUND_ROWS, since LimitOffsetIterator will use it// for reporting rows skipped by OFFSET or LIMIT. When we get rid of// SQL_CALC_FOUND_ROWS, we can use a local variable here instead.ha_rows *send_records_ptr;if (fake_select_lex != nullptr) {// UNION with LIMIT: found_rows() applies to the outermost block.// LimitOffsetIterator will write skipped OFFSET rows into the// fake_select_lex's send_records, so use that.send_records_ptr = &fake_select_lex->join->send_records;} else if (is_simple()) {// Not an UNION: found_rows() applies to the join.// LimitOffsetIterator will write skipped OFFSET rows into the JOIN's// send_records, so use that.send_records_ptr = &first_select()->join->send_records;} else {// UNION, but without a fake_select_lex (may or may not have a// LIMIT): found_rows() applies to the outermost block. See// SELECT_LEX_UNIT::send_records for more information.send_records_ptr = &send_records;}*send_records_ptr = 0;thd->get_stmt_da()->reset_current_row_for_condition();{auto join_cleanup = create_scope_guard([this, thd] {for (SELECT_LEX *sl = first_select(); sl; sl = sl->next_select()) {JOIN *join = sl->join;join->join_free();thd->inc_examined_row_count(join->examined_rows);}if (fake_select_lex != nullptr) {thd->inc_examined_row_count(fake_select_lex->join->examined_rows);}});if (m_root_iterator->Init()) {return true;}PFSBatchMode pfs_batch_mode(m_root_iterator.get());for (;;) {int error = m_root_iterator->Read();DBUG_EXECUTE_IF("bug13822652_1", thd->killed = THD::KILL_QUERY;);if (error > 0 || thd->is_error())  // Fatal errorreturn true;else if (error < 0)break;else if (thd->killed)  // Aborted by user{thd->send_kill_message();return true;}++*send_records_ptr;if (query_result->send_data(thd, *fields)) {return true;}thd->get_stmt_da()->inc_current_row_for_condition();}// NOTE: join_cleanup must be done before we send EOF, so that we get the// row counts right.}thd->current_found_rows = *send_records_ptr;return query_result->send_eof(thd);
}

函数过程浅析

1、is_simple()函数用来判断一个查询表达式是否有union或者多级order,如果没有说明这个查询语句简单。就执行add_select_number,TODO

2、运行ClearForExecution函数。

在初始化root迭代器之前,把之前的执行迭代器的数据清除。

3、运行get_field_list(),获取查询表达式的字段列表,并将所有字段都放到一个deque中,即mem_root_deque<Item*>;对于查询块的并集,返回在准备期间生成的字段列表,对于单个查询块,尽可能返回字段列表。

4、运行start_execution,准备执行查询表达式或DML查询。

5、接下来的一些操作与第二引擎有关,关于该引擎见https://www.h5w3.com/123061.html

总结一下就是:Secondary Engine实际上是MySQL sever上同时支持两个存储引擎,把一部分主引擎上的数据,在Secondary Engine上也保存一份,然后查询的时候会根据优化器的的选择决定在哪个引擎上处理数据。

我们这里先不看这一部分

6、如果该查询用于子查询,那么重新reset,指向子查询。

7、接下来是对于复杂句以及简单句的不同处理,从而给send_records_ptr赋值。

函数对于这个情况的解释如下:

  We need to accumulate in the first join's send_records as long aswe support SQL_CALC_FOUND_ROWS, since LimitOffsetIterator will use itfor reporting rows skipped by OFFSET or LIMIT. When we get rid ofSQL_CALC_FOUND_ROWS, we can use a local variable here instead.

情况一:如果该查询块具有UNION或者多级的ORDER BY/LIMIT的话

UNION with LIMIT的话,found_rows()用于最外层

LimitOffsetIterator跳过偏移量行写入send_records

情况二:如果是个简单句的话

found_rows()直接用到join上。

LimitOffsetIterator跳过偏移量行写入send_records

情况三:如果是UNION,但是没有LIMIT

found_rows()用于最外层。

8、重置计数器

9、接下来是一个对查询块遍历,逐个释放内存的操作,用以增加并发性并减少内存消耗。

10、初始化根迭代器

11、然后for循环,从根迭代器一直到引擎的handler,调用读取数据。如果出错就直接返回。

如果收到kill信号,也返回。

在循环中对send_records_ptr进行累加。

行计数器++,指向下一行。

12、将send_records_ptr赋值给该线程的current_found_rows

《MySQL 8.0.22执行器源码分析(2)解读函数 ExecuteIteratorQuery》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. AI强势来袭,锁上手机就真的安全了吗?
  2. Delphi 使用双缓冲解决图片切换时的闪烁问题 good
  3. 面向过程与面向对象引入三大特性事务
  4. maven spring profile 协同
  5. 全程图解交换机和路由器的应用
  6. jmeter 压测 RabbitMQ_单机
  7. Mike Krueger 加入Mono团队
  8. 二阶齐次线性微分方程的通解公式_高数大结局二阶常系数非线性齐次方程
  9. matlab 类型转换(类型判断)
  10. BLS数字签名算法介绍及拓展
  11. Vray2.0材质手册
  12. 四元式的翻译以及寄存器分配
  13. 雅虎邮箱(yahoo):应用程序专用密码登录
  14. Notion、印象笔记、Roam research…不知道笔记系统构建方式!怎么能选到对的笔记应用?
  15. java即时通讯im聊天源码,dubbo即时通讯im聊天源码,netty即时通讯im聊天源码,springboot即时通讯im聊天源码
  16. 一图掌握ISACA五大资格证书体系
  17. 年终盘点一 | 云原生的 2022 年:降本提效、全面 Serverless 化
  18. 【问题记录】js 更改数组中某字段名
  19. linux编译动态库未定义,GCC链接库的一个坑:动态库存在却提示未定义动态库的函数...
  20. vs2008与vss2005用后感

热门文章

  1. 程序员养家活口接私活必备网站(顺便用技术改变世界)
  2. java 时间戳 星期几_java自定义获取星期几、几点、几分。
  3. java 获取服务器网络名_java-siger java使用siger 获取服务器硬件信息(CPU 内存 网络 io等) - 下载 - 搜珍网...
  4. 模态对话框和全选反选
  5. js正则验证方法大全
  6. 响应式框架Bootstrap栅格系统
  7. Laravel 不同环境加载不同的.env文件
  8. html笔记(四)弹性盒+响应式
  9. 我的GMAIL下蛋了,要的请留下姓,名和email!!
  10. 【转】 差分约束系统详解(转化为最短路) (概念)