Optimizer Hints TIDB_INLJ 问题

为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。

  • 【TiDB 版本】:V3.0.8
  • 【问题描述】:同样的表结构以及数据,mysql 默认join使用 NLJ 算法join ,感觉TIDB_INLJ 并没有比NLJ 快。其次官方有没有关于TIDB_INLJ 的实现过程图?

1.方便的话提供一个表结构、数据规模 2.请提供相关的查询计划信息,具体命令参考这里 3. TIDB_INLJ 相关的说明可以参考这里

就算用了Optimizer Hints 执行从3S,变到了1.5S 。但我对比了没有用Optimizer Hints 时总的内存占用,与用了Optimizer Hints 的内存占用几乎一致。大概8G,感觉与NLJ的实现好像不一致啊 。如果按照NLJ的逻辑来说,我应该拿着s表的结果集,去e表中检索,将检索过的数据在提交到tidb。现在的表现给我的感觉与正常NLJ的逻辑不太符合。

tidb_hashagg_partial_concurrency,tidb_hashagg_final_concurrency我看文档默认值是4,但是在github 上测试TIDB_INLP时会把这两个置成1 ,请问,这两个变量设置不同值对应了对应了什么效果

你好,我是 TiDB 的研发工程师;看了下你上面的执行计划图,看起来 TIDB_INLJ(s) 并没有生效,因为执行计划里面的 Join 算子还是 HashLeftJoin,还是用的 HashJoin。

INLJ(s) 需要 s 在 join key 上有索引能够覆盖,s.SendOrderId 有索引覆盖吗,没有的话这个 hint 不一定能生效,然后就会回退到其他 Join 模式。

PRIMARY KEY (SendOrderId,CreateTime), KEY CreateTime (CreateTime), KEY Express (ExpressId), KEY ExpressNumber (ExpressNumber), KEY Device (DeviceSn), KEY idxUpdateTime (UpdateTime), KEY idxPwd (Password), KEY idxStatus (IsExpressIn,IsExpressOut,IsLinger), KEY idxOprExpress (ExpressInType,ExpressInOperatorId,IsExpressIn,IsExpressOut,ExpressOutOperatorId,ExpressOutType), KEY idxLingerSms (IsExpressIn,ExpressInType,IsLinger,ExpressInOperatorId), KEY idxExpressInTime (ExpressInTime), KEY idxLingerTime (LingerTime), KEY idexExpressOutTime (ExpressOutTime), KEY idxInOpr (ExpressInOperatorId), KEY idxOutOpr (ExpressOutOperatorId), KEY idxArriveOpr (ArriveOperatorId), KEY idxStationExpress (StationId,IsExpressIn,IsExpressOut,ExpressOutType,ExpressInType), KEY idxSendOrderId (SendOrderId), KEY Station (StationId,ExpressId), KEY Tenant (TenantId), KEY idxStationUpdate (StationId,UpdateTime), KEY idxTenantStation (TenantId,StationId,ExpressId) 是有的

e表也有

我想问下索引个数会有影响吗

虽然这个问题很蠢,但我还是想不出哪有问题,因为我另一个帖子https://asktug.com/t/topic/33196 验证过功能的可行性,是在想不到是什么问题了

hi 我是 tidb 研发,可以关注下 indexLookUpReader 151 上用的索引并不是 expressionNumber,其他分区都是走的 expressionNumber index,可以看下该分区上的索引是否存在和正确使用。

这个问题会去看看,但这个问题会影响TIDB_INLJ的使用吗?

我懵了

Hi @tonyhu214, 从执行计划来看,参与 Join 的这两个表是分区表, 目前分区表还不支持 Index Join。分区表是一个新功能,我们还正在完善中。对 Index Join 的支持我们后续想办法做一下。我记了一个 GitHub Issue 在这里 https://github.com/pingcap/tidb/issues/15612。后面可以关注下这个 Issue 的进展。

1赞

所以是两个都是分区表导致的是吗?我去拿源码里的test的脚本试试

是的,两个全是就不行:joy:

不全是,这个帖子中:

TIDB_INLJ() 这个 Hint 中指定的表是 Index Join 的内表,目前这个内表暂时不支持是分区表,只能是普通表。

那我如果查询指定两个分区是不是,index join 就会不生效。

那我如果查询指定两个分区是不是,index join 就会不生效。

对。

如果是分区表和普通表 Join,普通表上 Join 的那几个字段上有索引覆盖,也可以在 TIDB_INLJ() 中指定普通表,使这个 Join 的 SQL 使用 Index Join。

谢谢,学习到了

:+1: