TiDB控制执行计划有没有好的建议?是使用Hints更好还是通过执行计划绑定更好?

Hints 需要手动编写和维护,容易出现人为错误,对人员要求较高
但Binding同样需要明确查询的执行计划,且场景单一,需要根据场景不断的创建
两者都有不小的工作量,且效果不一定满意
不知道后面TiDB的优化器是否会更智能, 自动捕获绑定 (Baseline Capturing)也不知道能到哪种程度

当前,绑定通过生成一组 Hints 来固定查询语句生成的执行计划,从而确保执行计划不发生变化。对于大多数 OLTP 查询,TiDB 能够保证计划前后一致,如使用相同的索引、相同的 Join 方式(如 HashJoin、IndexJoin)等。但是,受限于当前 Hints 的完善程度,对于一些较为复杂的查询,如两个表以上的 Join 和复杂的 OLAP、MPP 类查询,TiDB 无法保证计划在绑定前后完全一致。

是的,可维护性和工作成本一直都是使用Hints和Binding的很难避免的问题,与其期待这些更好用,不如期待TiDB优化器的提升,这个才是从根本解决问题所在。

目前针对的Hints还是主要针对联机SQL,不过也有不少多表关联的场景,目前用到比较多的是一些强制选择索引以及强制指定关联顺序,对于多表关联,优化器选择的关联顺序比较差,通过指定正确的关联顺序之后,SQL执行效率还是有比较明显的提升;对于分析SQL,顶多是通过Hints或者Binding强制指定它走TiFlash,其他针对分析类SQL的绑定我们还是比较少。

统计信息没有过期的情况下,执行计划走偏,生产SQL不方便发出

各有优缺点, Hints灵活性较高,能够在不更改SQL语句的基础上临时指导优化器选择特定的执行计划, 对于一次性或短期性的优化非常有效,尤其在遇到优化器估计不准确的情况时,可以立即纠正执行计划。不适合长期或大规模维护,每次执行都需要手动指定Hint,不够自动化; 执行计划绑定, 自动化管理,一旦绑定生效,无需在每个SQL语句中都添加Hint,对于批量优化和持续稳定运行的SQL特别有用,但是当底层数据分布或表结构发生变化时,绑定的执行计划可能不再是最优的。

综合来看,如果你希望对特定SQL的执行计划有长期稳定的控制,并且愿意投入一定精力去评估和维护最优计划,则执行计划绑定是一个更好的选项。而在临时调试、应急处理或特定场景优化时,使用Hint更为直接和便捷。

这么精致啊,特殊感觉还是计划绑定

绑定如写死,感觉维护起来有劣处

建议能不用HINT和固定计划就不用,建议调整SQL方式解决问题

TIDB的统计信息收集感觉做的比较弱,从而带来执行计划的不准确,个人建议如果能明确某些sql就走指定的index,那就加force index,简单粗暴

如果你需要临时改变某个查询的执行计划,或者在开发阶段进行调优,使用Hints可能是一个更快捷的方法。如果你需要长期稳定地维护执行计划,尤其是在生产环境中,建议使用SPM。通过创建绑定,可以保证即使在统计信息变化或版本升级后,执行计划仍然保持不变。

嗯嗯,我们也是尽量先看能不能调整写法实现,调整之后没有效果,才会考虑执行计划指定

是呀,一个是TiDB的统计信息收集问题,还有一个是优化器执行计划的选择还有待提高。

如果使用SPM,对于MyBatis里的这种灵活SQL,那要创建的SPM语句可就太多了。

调整sql,别的事都让优化器自己选择。

最好的是改sql,但是大都数情况下需要开发配合