摘要:本节我们主要讨论的结果处理与发送。执行的累加结果存在中的变量里,结束后被返回给客户端。因为没有,所以返回的结果只有一条记录。每个执行的结果放在这对应的中,执行完毕后退出,而由主统计结果并发送最后的给。
本节我们主要讨论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/17646.html
阅读 3379·2021-11-22 09:34
阅读 650·2021-11-19 11:29
阅读 1350·2019-08-30 15:43
阅读 2232·2019-08-30 14:24
阅读 1866·2019-08-29 17:31
阅读 1223·2019-08-29 17:17
阅读 2616·2019-08-29 15:38
阅读 2728·2019-08-26 12:10