请问一下各位老师,为什么tidb的index join 工作过程中, 会生成一个 inner table row 的 hash table?之前一直认为比如a join b on a.id=b.id(假设a是外表),是从a表当中取数据,依次去b表根据关联条件进行关联就好了,为什么还会在b表生成1个hash table呢?
如果你按照单库的方式(因为所有的数据都在一个节点上),肯定没办法理解这个描述的
假设数据存在于多个节点中,inner worker 需要从 N个节点中去取数据,然后返回,返回之后的信息,怎么才能和 outer worker 的数据进行关联呢? 最简单的结构就是 hash了,通过 key 值关联
此外,返回的信息还需要临时留存,需要和 outer worker 做完计算后,才能释放…
传统数据库中outer表一条记录,然后去inner表中去cache中查询这个相关记录,一行一行的匹配。但是tidb是分布式架构而且存算分离,如果还是一行一行的去查找那就要去tikv中查找,中间经过大量网络交互。因此TiDB做了一些优化:1、将一行一行改为一批一批,也就是由Row改为chunk的方式。在不考虑并行的情况下,outer表先获取一个chunk的数据(这个chunk由小变大),然后再进行过滤+去重+排序等操作形成一堆keyRange,然后交给tidb后端进行组织加工成cop_task任务,发给tikv执行,但是tikv获取了一个outer表的chunk对应的所有数据以后,这些数据并不能确定和outer表的这个chunk的哪些记录对应啊,因此就通过hash table的方式来组织,来让outer表的chunk和inner表取过来的数据进行查找。
简单来说就是:传统数据库中不需要做hash table是因为outer表就是一行数据,直接匹配即可。tidb是chunk组织,需要走类似于走小表hash join的方式。
但是tikv获取了一个outer表的chunk对应的所有数据以后,这些数据并不能确定和outer表的这个chunk的哪些记录对应啊---->这里不能根据sql语句中的关联条件去确定嘛?
https://github.com/pingcap/tidb/issues/8470
https://github.com/pingcap/tidb/pull/8661
https://github.com/pingcap/tidb/pull/9571
outer表做hash那是index hash join吧?
是index hash join
根据关联条件去确定就是在hash table中确定的。