SQL选择非最优索引

【 使用环境 】测试环境
【 OB or 其他组件 】
【问题描述】
在使用ob数据库的时候发现,执行一个SQL时,发现有一张表没有选择最优索引,执行性能显著下降,通过/index(t index_name)/hint指定最优索引后变快,期间手动更新了表统计信息和直方图信息后,还是不会选择最优索引,这种情况只能手动强制指定索引了吗?

1 个赞

计划突变分很多情况,你这个手动更新了表统计信息和直方图信息这个只是其中一种,或者绑定outline或者强制走hint

1 个赞

这个SQL是动态的,查询条件中参数值会发生变化,不能绑定outline吧,要不参数值发生变化,SQL就匹配不上绑定的执行计划了吧

1 个赞

还有一个问题,就是这个SQL的参数传A值就走最优索引,传B值就走非最优索引,就很慢,为啥传B值就不走最优索引了,这是优化器的问题吗?

1 个赞

学习

1 个赞

如果sql_text的文本不一样 sql_id也是不一样的 如果不太一样 很相似 可以考虑format_sql_id绑定 可以看看文档
https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000005438226?back=kb
https://open.oceanbase.com/blog/22366619153

1 个赞

你看下传值A或B的筛选值的大小,是不是有大小账号问题,如果是多种情况可以根据mybatis 的if来判断做hint绑定

1 个赞

sql文本是什么样的呢?A值和B值 是同一个字段的不同值么?如果是这样 可以看看是否有大小账号的问题 看看两个值的数据量

1 个赞

bbb.txt (17.9 KB)
SQL和执行计划在这里,您帮忙看看
感觉是A表估行不准,导致得驱动表选择错误 但不知道为什么A表差这么多,这几张表得统计信息都手动收集了

1 个赞


从计划来看 应该是取值的时候 数据量不一样导致走的索引不一样 所以最后算子的吐行应该是有差别 估计是L表有大小账号的问题

可以使用obdiag在收集一下 两个的情况 再进一步分析一下
obdiag gather plan_monitor --trace_id YB420BA2D99B-0005EBBFC45D5A00-0-0
–env host=xx.xx.xx.xx --env port=2881 --env user=root@test --env password=*** --env database=test
https://www.oceanbase.com/docs/common-obdiag-cn-1000000005726947

1 个赞

参数是L表的字段,不是A表的,确实L表对传入的两个参数,数据量不一样,传A值得时候数据量为0,传B值得时候数据量为3万,我觉得不管是0还是3万,这个SQL的驱动表都应该选择L表才会快,但是传入B值的时候,A表变成了驱动表,从执行计划上看,是因为把A表行数估算成了7行,实际应扫描3.9万,我觉得最根本得原因是A表估行错误导致的执行计划错误,所以是不是应该解决A表估行错误的问题,这个该怎么解决呢?

1 个赞

建议你按照我发的 在收集一下信息 再看看 因为从L表数据来看 确实有大小表账号的问题 影响了执行计划
你可以不绑定索引 改变一下NLJ L和A的顺序 L表按照正常的B的值过滤 看看计划是不是会好 就可以验证了 你给的信息 在这里看不出来是不是统计信息有问题

1 个赞

学习