老哥,我是这么理解的。对于limit情况分两种:
1、select * from A limit N,这种简单语句如果limit下推,N>=10万则采用tidb_distsql_scan_concurrency对并发cop_task请求,如果N<10万则串行执行cop_task 请求,直到算子limit满足查询条件后终止后续cop_task请求。
2、其它复杂情况分两种:一种是keeporder=false的,采用tidb_distsql_scan_concurrency做并发,另一种是keeporder=true的,采用2做并发。这里走的是索引,keeporder=true,采用第二种情况。
第一个chunk也就是newFirstChunk初始值在limit算子这里是min(limit offset+count,max_chunk_size默认1024行),所以只要是limit N,这个N小于1024,那么第一次取得数据都是N条记录作为requireRows,但是接下来的我理解的都是按照min(剩余记录数,max_chunk_size)来取。因此这里的limit 32或者33 都应该在limit算子Open中的newFirstChunk调用一次next,然后在limit算子的Next中调用一次Next,但不需要读取数据了(因此执行信息中应该看到limit算子loop2次,table_reader算子loop1次)。
在做每个算子open操作的时候会调用newFirstChunk,如果算子需要的记录数比open时候newFirstChunk中的requiredRows小那么无需并行,直接一个cop_task完成,如果多那么会用到上述说的并行规则。
我的理解和这里的现象有一些出路,等待专家们协助解释解释。