资讯专栏INFORMATION COLUMN

MySQL内核技术之“结果发送”

shiweifu / 2960人阅读

摘要:本节我们主要讨论的结果处理与发送。执行的累加结果存在中的变量里,结束后被返回给客户端。因为没有,所以返回的结果只有一条记录。每个执行的结果放在这对应的中,执行完毕后退出,而由主统计结果并发送最后的给。

本节我们主要讨论COUNT的结果处理与发送。典型的SQL语句为:SELECT COUNT(*) FROM foo;

查询结果处理流程

结果累加调用链

JOIN::exec()--> 
do_select()--> 
sub_select()--> 
evaluate_join_record()--> 
end_send_group()--> 
init_sum_functions--> 
reset_and_add()--> 
aggregator_add()--> 
Item_sum_count::add()

返回结果调用链

JOIN::exec()--> 
do_select()--> 
sub_select()--> 
evaluate_join_record()--> 
end_send_group()--> 
send_data--> 
send_result_set_row()--> 
Item::send()--> 
Item_sum_count::val_int()

注意:上面的end_send_group实际上是evaluate_join_record()中的这行代码:rc= (*qep_tab->next_select)(join, qep_tab+1, 0);

整个逻辑是sub_select()中有个大循环,每次读出一条数据,然后进行evaluate_join_record()。在evaluate_join_record()中进行where判断等,然后调用end_send或者end_send_group进行最后处理。因为这里是COUNT因此,使用end_send_group()end_send_group调用reset_and_add进行累加。

发送完毕调用链(这个执行完客户端就有数据显示了)

dispatch_command()--> thd->send_statement_status()
多线程并发执行改造

现在我们来看看如何多结果处理流程进行改造。从上面分析可以看出,每次读出一条数据就要进入evaluate,调用end_send_group产看是否应该累加还是累加已经完毕。因此我们要在end_send_group加入新的逻辑,累加过程不变,但是累加完毕后,并不发送而是把结果放入select->m_parallel_results里,同时把done位置为true

而主线程要查看worker是否都完成了,即把结果放入select->m_parallel_results,如果是则进行所有的结果累加,还是加到item_sum中的count上。然后走正常的流程。

附录
MySQL的COUNT操作对应了Item_sum_count类,这个类是基于Item_sum类的。那么对应一个JOIN结构而言,里面包含了一个(其实是2个)Item_sum:分别是。Item_sum_count就被赋给了Item_sum这个成员变量。

执行的累加结果存在Item_sum_count中的count变量里,结束后被返回给客户端。因为没有GROUP BY,所以返回的结果只有一条记录。

改造的方法:因为一个JOIN对应了query的上下文,优化后的结果,如果同时被不同的thread执行,那么应该有多个count结果,而不是一个,这样我们就可以增加一个标志位为parallel,同时增加Item_sum_count中的member:count数组,其数量对应了多少个thread。每个thread执行的结果放在这对应的count中,执行完毕后worker thread退出,而由主thread统计结果并发送最后的count给client。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/62345.html

相关文章

  • MySQL内核技术结果发送

    摘要:本节我们主要讨论的结果处理与发送。执行的累加结果存在中的变量里,结束后被返回给客户端。因为没有,所以返回的结果只有一条记录。每个执行的结果放在这对应的中,执行完毕后退出,而由主统计结果并发送最后的给。 本节我们主要讨论COUNT的结果处理与发送。典型的SQL语句为:SELECT COUNT(*) FROM foo; 查询结果处理流程 结果累加调用链 JOIN::exec()--> d...

    fxp 评论0 收藏0
  • MySQL内核技术“聚合操作”

    摘要:因为上一篇文章着重针对操作的结果发送,文本继续以操作为例阐述的聚合操作。我们需要把这里进行改动类型判断很多时候我们要判断聚合函数的类型。在中定义了的类型我们可以通过这些类型来判读当前具体的聚合操作。 本文可以结合我的上一篇文章结果发送结合来看。因为上一篇文章着重针对COUNT操作的结果发送,文本继续以COUNT操作为例阐述MySQL的聚合操作。 简要来说调用关系: JOIN::opti...

    kohoh_ 评论0 收藏0
  • MySQL内核技术"查询流程"

    摘要:本节讨论是如何进行数据查询和读取的。首先看一下调用过程实际上是或实际上是是从派生出来的,用来做实际查询的。里面的重要结构有这里面最重要的是结构,其中比较重要的几项是由调用的,常用的方式是,这里的实际上就是。 本节讨论MySQL是如何进行数据查询和读取的。首先看一下调用过程: JOIN::exec()--> do_select()--> sub_select()--> read_reco...

    dinfer 评论0 收藏0
  • MySQL内核技术“Opt_trace_系列”

    摘要:在主执行函数中位于在执行操作如前,基于创建出和。注意当执行完毕后,这两个变量自动销毁。这些信息在整个执行过程中都是需要的。除了基类为定义在中。代码用的最多的是两个派生类和,以及 MySQL代码使用了大量Opt_trace相关结构,先看代码中的一段注释: This optimizer trace is aimed at producing output, which is reada...

    QiuyueZhong 评论0 收藏0
  • MySQL内核技术"LIKE"和"IN"

    摘要:在中,像这些操作符都属于类型在中,这些都是。先说,它对应的类为位于中。进行的时候实际上是在中进行折半查找。因此如果想做并发执行,多线程就共用了该变量。解决办法和上面类似,独立出一个数组,来对应不同线程即可。 在MySQL中,像LIKE、IN、>、= 这些操作符都属于Item类型(在Postgres中,这些都是expression)。本节中,我们详细说说LIKE和IN是怎么实现的。 先说...

    edagarli 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<