表顺序影响执行计划

【TiDB 版本】 5.0.2

【问题】 SQL中表顺序不同 ,影响执行计划
原始SQL,顺序b c a ,a c关联 ,a全表扫描没走主键


改写顺序后,a走主键索引

2 个赞

这个比较正常阿,left join和 right join 都会转换为 inner join,根据代价的计算结果进行优化,这个优化出来的效果不一定是你想要的;

所以,必须人为的根据数据的情况,进行优化处理
另外数据变动的百分比,也会影响到统计结果,进一步导致结果上的偏差(代价模型中的参考数据来源于表数据的收集参考值)

1 个赞

在进行数据库开发的过程中,可以参阅一下社区同学整理的开发规范

https://asktug.com/t/topic/93819

1 个赞

这不是开发设计的问题

1 个赞

我的理解传统数据库应该是不会被顺序影响,都走同样的索引,老哥辛苦试下显示写inner join,而不是用·,·,看看是否有区别

1 个赞

盲猜是 join order 的问题。你这个例子让我感觉,tidb 的 join order 还是有比较长的路要走。
我特别想放网上一张很火的图片:

我看不懂,但我大受震撼.jpg

3 个赞

方便的话可以导出这三个表的表结构和统计信息,可以替换掉敏感的表名或字段名
show create table xxx_product;
show create table xxx_user;
show create table xxx_user_product;

导出统计信息后,也可以 sed 替换掉文件中的的表名和列名等
https://docs.pingcap.com/zh/tidb/stable/statistics#导出统计信息

1 个赞

table.txt (28.4 KB) stats.txt (24.9 KB)
见附件,因有大量个人信息数据未导出统计信息及直方图信息

1 个赞

inner join 也是一样的,没变化

1 个赞

麻烦分别看下两种写法 explain analyze 结果

1 个赞

修改表顺序后的执行计划


走全表扫描的写法执行时间太长

你好,可以将 now() 值固定为一个值看看,不同的时间端执行,now 可能会有一定的影响

固定时间也没有效果

看了两个截图,可能是优化器的关系,对于链表方式一个选择了hashjoin,一个选择了indexhashjoin,辛苦显示指定下a,c联表方式 ```
/*+ INL_HASH_JOIN(a,c) */

辛苦用原表名呢,不用a,c,你看现在的执行计划还是hashjoin,而不是indexhashjoin

也是没效果,选择hashjoin应该是因为有全表扫描

https://docs.pingcap.com/zh/tidb/v4.0/join-reorder#join-reorder-算法限制,看看这个,你把c.serial_number这个条件去掉,看下二者的执行计划一致不

hint 加了之后有 warning 提示。show warnings 看看提示。